公开记录
软件健康报告模式 0.26.0 · 指标 1.13.0 · 2026-07-22 11:29 UTC

ShovelsAI / shovels-cli

GoMIT★ 9 星标⑂ 0 复刻始于 2026年3月在 GitHub 上查看 ↗

ShovelsAI/shovels-cli 的健康指数为 100 分中的 51 分,处于「中等」区间。 其得分最高的类别是AI Readiness(78/100),最低的是Community & Adoption(31/100)。 最近一次更新在 2 天前。 近期的大部分工作由 1 位贡献者完成。

51
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

Shovels组织
14 关注者4 个公开仓库始于 2015年8月

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

按类别列示的指标

活力

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

77良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 2 天前
3.5/36提交节奏 — 52 周中有 5 周有提交
18/18提交量 — 最近一年 135 次提交
10/10OpenSSF Scorecard:Maintained — 12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year135
human_commit_share0.96
days_since_last_push2
active_weeks_last_year5

发布纪律

90优秀
评分方式
27/27有发布版本 — 已发布 10 个发布版本
36/36发布时效 — 最近一次发布版本于 4 天前
27/27发布节奏 — 约每 15.2 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — Project has not signed or included provenance with any releases.
所用输入
releases_count10
latest_release_tagv0.7.1
releases_from_tags
days_since_latest_release4
mean_days_between_releases15.2

社区与采用

项目是否拥有用户、下载量与关注度,并具备欢迎贡献者参与的配置?

31存在风险 · 占总体的 18%
评分方式
14.6/60星标 — 9 个星标
0/25复刻 — 0 个复刻
0/15关注者 — 0 位关注者
所用输入
forks0
stars9
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

社区健康

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

可持续性与治理

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

45存在风险 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
0/22.5提交分布 — 头号贡献者编写了 100% 的提交
1.4/13.5贡献者广度 — 1 位贡献者
3/10OpenSSF Scorecard:Contributors — project has 1 contributing companies or organizations -- score normalized to 3
所用输入
bus_factor1
contributors_sampled1
top_contributor_share1
评分方式
0/46.8议题解决 — 没有议题或无数据
38.2/38.3PR 接受 — 已裁定的 PR 中 12/12 已合并
0/15OpenSSF Scorecard:Code-Review — Found 0/9 approved changesets -- score normalized to 0
所用输入
merged_prs12
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
已排除计分(无数据或不适用):议题解决。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
8.5/25所有者影响力 — ShovelsAI 有 14 位关注者
17.1/25既往记录 — 4 个公开仓库,账户约 10 年
所用输入
followers14
owner_typeOrganization
is_verified
owner_loginShovelsAI
public_repos4
account_age_days3,978

工程质量

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

53中等 · 占总体的 20%

工程实践

68中等
评分方式
24/24CI 工作流 — 2 个工作流
24/24存在测试
0/16Linter 配置
0/9.6Pre-commit 钩子
0/6.4.editorconfig
20/20OpenSSF Scorecard:CI-Tests — 6 out of 6 merged PRs checked by a CI test -- score normalized to 10
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config

文档

30存在风险
评分方式
30/30README
0/25文档目录
0/15文档 / 主页站点
0/10仓库描述
0/10主题标签
0/10Wiki
所用输入
topics
has_wiki
homepage
has_readme
has_docs_dir
has_description

安全

可见的安全与供应链实践是否稳固,且不存在未解决的高风险司法辖区暴露?

43存在风险 · 占总体的 16%

安全态势

43存在风险
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
2.2/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 6 out of 6 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/9 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
7.5/7.5Maintained — 12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 15 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate4.3

AI 就绪度

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

78良好 · 占总体的 0%
评分方式
45/45代理指令 — CLAUDE.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 96 次人类提交中有 87 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.906
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes5,541
评分方式
12.6/18一条命令的引导启动 — go.mod(工具链约定,无任务运行器)
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — Go(静态类型)
10/10可复现环境 — lockfile
0/10已体现的代理实践 — 最近 100 次提交中没有代理编写的提交
8/8自动化维护 — 最近 100 次提交中有 4 次为自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfilesgo.sum
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configs
agent_commit_share0
toolchain_manifestsgo.mod
dependency_bot_commit_share0.04
评分方式
45/45可类型检查的代码 — Go(静态类型)
54.4/55可控的文件大小 — 采样的 85 个源文件中有 1 个超过 60KB
所用输入
primary_languageGo
largest_source_bytes83,253
source_files_sampled85
oversized_source_files1

关键数据

9GitHub 星标
1贡献者
135最近 12 个月提交数
2距最近推送天数
10发布版本数
1巴士系数(bus factor)
0开放议题
Go软件包生态系统数

数据采集警告

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • Could not fetch go package 'github.com/shovels-ai/shovels-cli' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

更多细节

OpenSSF Scorecard 4.3 / 10
4.3综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。Scorecard v5.5.0 · 2026-07-22 11:29 UTC

10Binary-Artifactsno binaries found in the repo
3Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests6 out of 6 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/9 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities15 existing vulnerabilities detected
直接依赖 4
注册表软件包版本约束清单文件
Gogithub.com/creativeprojects/go-selfupdatev1.5.2go.mod
Gogithub.com/spf13/cobrav1.10.2go.mod
Gogithub.com/spf13/pflagv1.0.10go.mod
Gogopkg.in/yaml.v3v3.0.1go.mod
全部依赖 未采集

本报告未能采集到解析后的依赖集合:GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 459,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "Go": 807434,
        "Shell": 6365
      },
      "pushed_at": "2026-07-20T03:14:49Z",
      "created_at": "2026-03-02T14:20:19Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-17T15:58:25Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Go",
      "significant_languages": [
        "Go"
      ]
    },
    "owner": {
      "blog": "https://www.shovels.ai",
      "name": "Shovels",
      "type": "Organization",
      "login": "ShovelsAI",
      "company": null,
      "location": "United States of America",
      "followers": 14,
      "avatar_url": "https://avatars.githubusercontent.com/u/14048501?v=4",
      "created_at": "2015-08-31T04:06:31Z",
      "is_verified": null,
      "public_repos": 4,
      "account_age_days": 3978
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.7.1",
          "kind": "patch",
          "published_at": "2026-07-17T16:00:07Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-06-01T23:50:59Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-05-31T20:49:29Z"
        },
        {
          "tag": "v0.5.1",
          "kind": "patch",
          "published_at": "2026-04-03T08:23:57Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-03-09T11:24:03Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-03-08T20:53:53Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-03-05T09:32:38Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-03-03T00:09:13Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-03-02T23:50:52Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-03-02T16:43:05Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "18e79b023de69c64705b3ad9f9548e583a8270be",
          "body": "Four persistent flags (--limit, --max-records, --base-url, --timeout)\nhand-wrote a (default ...) note in their usage string while cobra also\nauto-appends its own for any flag with a non-zero default, so --help\nrendered each default twice. Drop the manual text; cobra supplies it.\n\nFixes ENG-3840",
          "is_bot": false,
          "headline": "Remove duplicate default annotations from global-flag help (#14)",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-07-17T15:57:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "70b6e80e355a927f57bad79e001289f34e357a60",
          "body": "Verify a blind agent can discover and use decisions search for a\nnatural-language zoning task, satisfying the usability gate for the\nnew command. The task is state-level to avoid ZIP, which decisions\nrejects, and city-resolution flakiness. Sparse decisions data makes\nusability the gate, not result volume, so empty data is accepted and\na decisions-distinctive field is checked only when data is present.",
          "is_bot": false,
          "headline": "Add zoning decisions eval scenario",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-06-01T23:47:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0fccb7d2eea7bbc0b58f543f5c0426b46b4dc07",
          "body": "Register the --schema flag on both decisions subcommands and route it\nthrough the offline schema lookup, so an agent can discover the field\nset and meta shape without spending credits on a live call.\n\nList decisions in the root help among the commands that answer\n--schema.",
          "is_bot": false,
          "headline": "Wire --schema onto decisions search and get",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-06-01T23:47:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f76640fa82f9fac5098031ed1c1149add755d65f",
          "body": "Add the decisions search and get entries to the generated schema so\nagents can inspect their fields offline via --schema.\n\nThe generator distinguishes batch-get meta from paginated meta: a get\nreturns a fixed set of records keyed by ID, so its envelope reports\ncount, missing, and credit fields but n\n[…]\naginates and does. Encoding that distinction in the get branch\nyields a correct decisions get schema and aligns the sibling permits\nand contractors get schemas, whose envelopes likewise omit has_more.",
          "is_bot": false,
          "headline": "Generate offline schema for decisions commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-06-01T23:47:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ce90a6f3aa4d9d1ca391b5e7ae6b74ad6b9f43f6",
          "body": "Agents need to fetch specific zoning and land-use decisions by ID in a\nsingle batch request. The command accepts up to 50 IDs as positional\narguments, returns found decisions in the data envelope, and surfaces\nany unknown IDs in meta.missing so callers can tell which lookups\nfailed.",
          "is_bot": false,
          "headline": "Add decisions get subcommand",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-06-01T23:47:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4f87df431529b39d7fdfc473fd15529f4f04c1ed",
          "body": "Wrap GET /decisions/search as a new top-level decisions resource with\na search subcommand, so agents can query zoning and land-use decisions\nby geography and date range.\n\nDecisions owns its flag set, validation, and query builder rather than\nreusing the permits-shaped search helpers, because it rejects ZIP\ngeo_ids, emits decision_* date params, and exposes a distinct filter\nset. Only resource-agnostic plumbing (pagination, dry-run, timeout,\nclient construction, and API-error mapping) is shared.",
          "is_bot": false,
          "headline": "Add decisions search command",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-06-01T23:47:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "028e6ec40cb16d513d74a4c116096191ba57e10c",
          "body": "The shared cause text is reused by state and zip coverage, so the\nzero-permits explanation is worded by geography rather than naming a\njurisdiction, keeping it accurate across all five coverage commands.",
          "is_bot": false,
          "headline": "Explain why a coverage field is missing",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-05-31T20:44:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "be59b18e096b3e4e509c153353b1662c28c4fc1e",
          "body": "Imperative-task agents read search help then immediately query,\nskimming past a coverage tip placed lower down. Surfacing the\ncredit-exempt coverage directive before the required-flag walls\ncatches them before the first credit-burning query.",
          "is_bot": false,
          "headline": "Lead search help with coverage pre-flight",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-05-31T20:44:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bd01126f85a8dfb6aecf34d6b043038f509d7f82",
          "body": "Root, search, and metrics help direct agents to check coverage before\nrunning field-dependent searches, so they confirm field availability\nwithout spending credits on queries the data cannot support.\n\nThe coverage workflow only references geographies coverage supports\n(city, county, jurisdiction, st\n[…]\ndoes not imply address\ncoverage exists. The directive frames coverage as flagging the fields\nthat are NOT reliably populated, rather than implying a positive field\nlist or a single total-count scalar.",
          "is_bot": false,
          "headline": "Point help at coverage as credit-exempt pre-flight",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-05-31T20:44:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cfca373e3121880abcda1d90644c28b6de79196e",
          "body": "The /v2/usage response now returns a per-day daily_usage array over the\nrolling 30-day window, so the help text describes it for agents reading\n--help before inspecting output.",
          "is_bot": false,
          "headline": "Document daily_usage breakdown in usage help",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-05-31T20:44:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cfb4d7b5f290c701b4b4545226e32fcbb251540d",
          "body": "Coverage commands are non-paginated and credit-exempt, so they need\ndistinct schema generation: an empty meta envelope, a positional GEO_ID\nplus coverage date filters, and a surfaced tier enum. A loud-fail guard\nnow aborts generation when a named response schema yields zero fields,\nturning a silent typo into a build failure.",
          "is_bot": false,
          "headline": "Add coverage --schema catalog entries",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-05-31T20:44:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "34e3270efea7f586097a163ea583f232af00b645",
          "body": "Wraps GET /meta/coverage so agents can check which permit fields are\nreliably populated for a geography and date window before spending\ncredits on a query. Coverage is credit-exempt and non-paginated, so it\nuses a single Get and maps the items array into the standard data\nenvelope.",
          "is_bot": false,
          "headline": "Add coverage command for all five geographies",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-05-31T20:44:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b8753020e2a8f42a171714a8ff242c97526816de",
          "body": "Mechanical change across 14 call sites: replace field-by-field\nunpacking with output.PrintPaginated(w, result).",
          "is_bot": false,
          "headline": "Update all PrintPaginated callers to pass result directly",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-04-03T08:16:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2bb2e5a60200be7255cd3eafd64c7278bada5c1d",
          "body": "Replaces the 6-parameter signature with (io.Writer, *PaginatedResult).\nThe output layer reads fields directly from the result struct, so\nadding fields to PaginatedResult no longer requires updating callers.",
          "is_bot": false,
          "headline": "Simplify PrintPaginated to accept *PaginatedResult",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-04-03T08:16:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2116073a50b505382f05cdaf88ad86e913248e74",
          "body": "credits_used reported only the last page's cost because PaginatedResult\nreused the per-response CreditMeta struct. Replace Credits CreditMeta\nwith explicit CreditsUsed/CreditsRemaining *int fields so the type\nsystem distinguishes per-request from aggregate credit data.\n\nAdd creditsUsedPtr helper and four tests covering multi-page\naccumulation (cursor exhausted and limit reached), single-page\npass-through, and nil preservation when API returns no credit headers.",
          "is_bot": false,
          "headline": "Accumulate credits_used across paginated pages",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-04-03T08:16:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9607e9b308b77f1b305914e7ceb7850f52c2611b",
          "body": "The API accepts up to 100 items per page but the CLI\ncapped at 50, doubling HTTP round-trips for large\nresult sets. Raising apiPageSizeMax to 100 halves the\nrequest count for any fetch exceeding 100 records.",
          "is_bot": false,
          "headline": "Raise API page size from 50 to 100",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-09T11:07:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "668377e649b7e2003a129b368f11bd521cafa468",
          "body": "Reject invalid --contractor-classification values before making an API\ncall, matching the client-side validation pattern used for --status and\n--property-type. Includes 13 canonical enum values from the OpenAPI spec,\nhelp text examples, and schema descriptions.",
          "is_bot": false,
          "headline": "Add classification flag validation",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-09T11:07:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d73fd8e86503d047c1136dc33e92f0ca83f5423d",
          "body": "The CLI hard-rejected 6 valid API property types (agricultural,\nvacant land, exempt, miscellaneous, office, recreational) because\nvalidPropertyTypes only contained residential, commercial, industrial.\n\nExpand the validation slice, update help text and schema descriptions\nacross all commands that accept --property-type, and regenerate\nschema_data.go. E2e tests assert all 9 types in every help context.",
          "is_bot": false,
          "headline": "Accept all 9 API property type values",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-09T11:07:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "468fc586166813108d3131db50ff2436f0d8f388",
          "body": null,
          "is_bot": false,
          "headline": "Document pre-commit hook setup in CLAUDE.md",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "babb5c3d31959c09f14c764cb882a2b01595aeb1",
          "body": "Run gofmt on cmd/schema_test.go and e2e/schema_test.go to fix CI\nlint failure. Add .githooks/pre-commit that runs gofmt, go vet, and\ngo test before each commit to catch these locally.",
          "is_bot": false,
          "headline": "Fix gofmt and add pre-commit hook mirroring CI",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b066eb9e645805781957442bab25bf56a149de7",
          "body": "The schema generator wrote schema_data.go directly to disk without\nrunning gofmt, causing persistent formatting drift. Buffer output\nand apply go/format.Source before writing so regeneration always\nproduces gofmt-compliant code.",
          "is_bot": false,
          "headline": "Format generated schema via go/format",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "219421bae8ff77052c7366d34f76b44ef6aba165",
          "body": "Agents skip --schema and guess at field semantics. A short tip in\neach data command's help text nudges them to inspect metadata first.",
          "is_bot": false,
          "headline": "Add --schema discovery hints to help text",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "949f6b7bbc4595ab10fc6ffe7f07679aefa82ecb",
          "body": "Agents try --id as a flag on commands that accept ID positionally,\ngetting cryptic \"unknown flag\" errors. Each ID-accepting command\nnow has a Note block with correct/incorrect usage examples.",
          "is_bot": false,
          "headline": "Add positional arg hints to ID commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b3bf5977b15c03f93418468b9ca22e1bd4fd5d9",
          "body": "Spec requires 3-5 lines for scoping section and 1-2 lines for\n--no-tallies warning. Fix the upper bound from 6 to 5 and add\na missing conciseness assertion for the flag description.",
          "is_bot": false,
          "headline": "Tighten e2e boundary assertions",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a0f4e1922d0b2bf64d7aafbebc722e916bad4fa7",
          "body": "Agents reading only --help confuse global lifetime stats (permit_count)\nwith search-filtered results (tag_tally), leading to absurd analysis.\nThe scoping section and --no-tallies warning make the distinction clear\nwithout requiring agents to discover --schema.",
          "is_bot": false,
          "headline": "Add scoping guidance to contractor search",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b35515b77eae15d1016ab59aa3a3322c4b3c158a",
          "body": "Refactor to table-driven assertions covering every GLOBAL field\n(permit_count, avg_job_value, total_job_value, avg_construction_duration,\navg_inspection_pass_rate) and every FILTERED field (tag_tally,\nstatus_tally) to ensure complete boundary coverage.",
          "is_bot": false,
          "headline": "Cover all contractor scope fields in e2e tests",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "62ec07e3473a6505e65c0b3e82fdc327e846ce10",
          "body": "Agents confuse contractor lifetime stats (permit_count=93,259) with\nsearch-filtered results (tag_tally sum=39), producing absurd analysis.\nLabel aggregate fields as GLOBAL or FILTERED so agents know which\nvalues reflect search parameters and which are lifetime totals.",
          "is_bot": false,
          "headline": "Add scope labels to contractor schema fields",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1cf79af5c809693206a24a50847945cf44149e2f",
          "body": "Agents read the description text but skip the separate unit metadata\nfield, causing 100x dollar errors. All 20 monetary fields now include\n\"in cents (divide by 100 for dollars)\" directly in the description.",
          "is_bot": false,
          "headline": "Bake units into schema field descriptions",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "69091bffa6b212c6d77a53126f048b70d7c14d50",
          "body": "Flag descriptions and schema filter entries said \"in dollars\" but the\nAPI accepts cents. Corrected all four monetary flags to say \"in cents\"\nwith dollar-equivalent conversions, added Unit:\"cents\" metadata to\nschema output, and updated the --no-tallies description to warn that\ntallies are the only search-filtered contractor fields.",
          "is_bot": false,
          "headline": "Fix monetary filter help text units",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-08T20:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b26e9e3fc205bf82a83e6b872b7c8571877b8b0",
          "body": "CI lint requires all files pass gofmt. The schema generator\nand schema e2e tests had formatting drift.",
          "is_bot": false,
          "headline": "Fix gofmt formatting in generated schema data",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a7787ebf75795958ef943efc76edee5059831cf7",
          "body": "Jq eval scenarios must prove the agent discovered jq rather than\nproducing lucky output. Monthly breakdowns must show temporal\nstructure, not just multi-entry JSON.",
          "is_bot": false,
          "headline": "Strengthen eval output validators and ratings",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d30cd722a161c32e3fb3890197fb3c3b7120c4a",
          "body": "Blind agents need to discover metrics, schema, dry-run, and jq\npipeline workflows without hints. Six new scenarios validate\ndiscoverability of v0.3.0 features alongside existing four.",
          "is_bot": false,
          "headline": "Add LLM eval scenarios for new commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6dc2eae9cca11922818b1da23e536a571f444a33",
          "body": "Cobra skips PersistentPostRunE when RunE or validation\nreturns an error, leaving the update goroutine orphaned.\nDefer the wait in Execute() to guarantee cleanup regardless\nof command outcome.",
          "is_bot": false,
          "headline": "Wait for update goroutine on all exit paths",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fdf714432ead9ab479f5f0e4d81f3ba269844bd3",
          "body": "New users without an existing config directory had cache writes\nfail silently, causing update checks on every CLI invocation\ninstead of respecting the 24-hour throttle.",
          "is_bot": false,
          "headline": "Create parent dirs in update cache writer",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d35e763c67c83cbac703ca500a10958fe3816651",
          "body": "Users should always run the latest CLI without manual intervention.\nAll failures are silent to avoid disrupting the user's command.",
          "is_bot": false,
          "headline": "Add background autoupdate via GitHub Releases",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7cef4ccc326f021d464cde9c2e127a7ce3fa9da3",
          "body": "Users need a way to opt out of background autoupdate. The Autoupdate\nfield defaults to true (nil = enabled) so existing configs work\nwithout changes.",
          "is_bot": false,
          "headline": "Add autoupdate config field",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5224df8f56a96088b921defde5f28363d9b927d8",
          "body": "Schema and --schema flag need regression coverage to catch init\nordering issues and ensure offline operation without auth.",
          "is_bot": false,
          "headline": "Add e2e tests for schema introspection",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f7f9bf797dc2e7f419d3574238f003ab2b153478",
          "body": "LLM agents need offline access to response field schemas to construct\njq pipelines without trial-and-error API calls or auth credentials.",
          "is_bot": false,
          "headline": "Add schema command and --schema flag",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd190e3a60e91c3f3a274af167821ad57d25e47a",
          "body": "LLM agents need offline access to annotated response schemas\nto construct jq pipelines without trial-and-error API calls.\nCommitted Go source ensures schema availability without\nruntime OpenAPI dependency.",
          "is_bot": false,
          "headline": "Add schema data generation pipeline",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f73ff5cf62b0e43c4dec589626cfa5a89b9acc55",
          "body": "Global flags like --timeout must be validated even when --dry-run\nshort-circuits before client creation, so invalid values are\nnever silently accepted.",
          "is_bot": false,
          "headline": "Wire --dry-run into all data commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8fd20374b0395434f7f2e38aafd280dd71a332d5",
          "body": "LLM agents and pipeline builders need to inspect resolved HTTP\nrequests without spending credits or hitting the API.",
          "is_bot": false,
          "headline": "Add --dry-run flag infrastructure",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8d8423dee2c518bce5acbfbb3916053090cf7029",
          "body": "The version command needs API credentials from environment\nvariables and flag overrides even when the config file is\nmalformed, otherwise data_release_date is always null despite\nvalid auth being available.",
          "is_bot": false,
          "headline": "Preserve env vars in version config fallback",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4692a62c1d3562badb28ef63b9c6e76dc42f88fd",
          "body": "Only the version command needs to survive config failures.\nOther commands depend on correct config values and should\nfail explicitly rather than proceeding with empty defaults.",
          "is_bot": false,
          "headline": "Scope config-error bypass to version only",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b407fac6a99a616c34cfdc18ff4ede2e90ff36a2",
          "body": "Version must always exit 0 regardless of environment state,\nsince it is the primary diagnostic tool when configuration\nis broken.",
          "is_bot": false,
          "headline": "Harden version command against config failures",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d8918c5c398ffac92ba748aa7a6d7884060d9f43",
          "body": "Users and agents need to know how current the API data is\nbefore trusting query results. The version command degrades\nsilently to null when auth is missing or the API is unreachable.",
          "is_bot": false,
          "headline": "Add data freshness to version command",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e8878e423184e304ffb7eafe76b0744d5811189e",
          "body": "Exposes PII resident data at GET /v2/addresses/{geo_id}/residents\nwith paginated output. Help text documents the personal nature of\nthe data and the address-first resolution workflow.",
          "is_bot": false,
          "headline": "Add addresses residents subcommand",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cd4f997d2b6f43757296e2419fb74011b7afa891",
          "body": "Completes geographic search coverage so users can discover\nzip codes and state abbreviations for --geo-id on other\ncommands without needing to know them in advance.",
          "is_bot": false,
          "headline": "Add zipcodes and states search commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26527756184f0e6739abf1de258e065658e743f3",
          "body": "Counties, jurisdictions, and addresses each need current and monthly\nmetrics endpoints. Addresses metrics omits property_type to match the\nAPI contract where addresses lack that dimension.",
          "is_bot": false,
          "headline": "Add remaining geo-metrics commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d690fd95f8975d3249bdb963675a876cd466e8b0",
          "body": "Cities metrics validation and request plumbing needs reuse across\ncounties, jurisdictions, and addresses without copy-paste divergence.",
          "is_bot": false,
          "headline": "Extract shared geo-metrics helpers",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bfd546d434d164cbcc222352f70826808374b501",
          "body": "Cities need geo metrics endpoints for permit activity analysis.\nThe current variant returns aggregate snapshots while monthly\nreturns time-series data with date fields over a specified range.\nDate flags are rejected on current with a clear message directing\nusers to the monthly variant.",
          "is_bot": false,
          "headline": "Add cities metrics current and monthly commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-05T09:29:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "954253207d87cb961e5587430b9d76a56f5c1d7a",
          "body": null,
          "is_bot": false,
          "headline": "Document LLM eval suite in CLAUDE.md",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-03T01:25:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2953efc83d5d70f6ed7529b41090d12c81f2fea2",
          "body": "Spawns blind Claude agents that discover and execute CLI commands\nusing only --help output. Four natural-language scenarios test\npermit search, contractor lookup, geo_id resolution, and tag\ndiscovery. Run with: go test -tags=eval ./evals/... -v -timeout 10m",
          "is_bot": false,
          "headline": "Add LLM eval suite for CLI help text usability",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-03T01:17:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15cf37aa08e9358b1fbda7e942e7bbe85348747d",
          "body": null,
          "is_bot": false,
          "headline": "List valid contractor classification values in help text",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-03T00:07:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e3dd6a8e0e700dba23b7e3c2f80b21de0308c14b",
          "body": null,
          "is_bot": false,
          "headline": "Fix Go Report Card badge URL casing",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:53:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "719ecaf9bb4b32096f31a5fe994c2fb6daaa90bc",
          "body": "Agents and engineers can see the tag-push release\nprocess without reading CI config files.",
          "is_bot": false,
          "headline": "Document release workflow in CLAUDE.md",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8232e032265b07824e736d51e8d82b7974f1d357",
          "body": "The command tree must reflect all commands visible in\n`shovels --help`, including Cobra built-ins.",
          "is_bot": false,
          "headline": "Add completion and help to README command tree",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ad06478421157935ffc670fa0c3eef1937dcb7a9",
          "body": "All --geo-id references now show cities search, counties search,\njurisdictions search, and addresses search as resolution paths.\nRoot help lists the four new commands in available resources.",
          "is_bot": false,
          "headline": "Update help text for geo resolution commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2f82fee88f5102fa5c5293bcbea494bbfcbac13f",
          "body": "All --query validation errors now use the same format\nacross cities, counties, jurisdictions, and addresses.",
          "is_bot": false,
          "headline": "Standardize addresses search error message",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c83bf42fffc7e18008c6ff0256a3c3c867f4ae47",
          "body": "Invalid property types cause silent empty results\nfrom the API. Validation catches mistakes early\nwith an actionable error listing valid options.",
          "is_bot": false,
          "headline": "Validate --property-type enum values",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "11ba9c5bd2bf3b400167dda7f580089f50352860",
          "body": "Agents need to discover valid --tags values instead of guessing,\nwhich leads to silent empty results from invalid tag names.",
          "is_bot": false,
          "headline": "Add tags list command for tag discovery",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b91b8634d42f7369dd62f7383aaf2b999f6a1ef",
          "body": "Agents need to resolve jurisdiction names to Shovels geo_ids for\njurisdiction-level permit and contractor searches.",
          "is_bot": false,
          "headline": "Add jurisdictions search for geo_id resolution",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c5b7d1192948ce4c079fbd427235f38c4c62a314",
          "body": "Agents need to resolve county names to Shovels geo_ids for\ncounty-level permit and contractor searches.",
          "is_bot": false,
          "headline": "Add counties search command for geo_id resolution",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f80f09024a535d728798af27889a710890068d55",
          "body": "The /cities/search endpoint ignores the size parameter and\nreturns all matches. The mock handler now does the same, so\nthe limit test verifies client-side truncation.",
          "is_bot": false,
          "headline": "Match cities mock to real endpoint behavior",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b2228c59ec5dc506fa7e7f2fdcfe18017fa433f",
          "body": "Endpoints like /cities/search ignore the size parameter and\nreturn all matches at once. The paginator now slices results\nto the requested limit when no cursor is present.",
          "is_bot": false,
          "headline": "Truncate single-page responses to effective limit",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8fe84717b5338851fc44aacd18281203ff2ef755",
          "body": "Geo_id validation rejects prefixed formats like ZIP_90210.\nE2e tests use bare 5-digit codes to match the accepted format.",
          "is_bot": false,
          "headline": "Use bare zip codes in e2e tests",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "715c4c8ee5f59bbc79416f57ae4cdc4b92968d86",
          "body": "Agents need to resolve city names to Shovels geo_ids before\nsearching permits or contractors by city. This was the primary\ngap found in blind usability testing.",
          "is_bot": false,
          "headline": "Add cities search command for geo_id resolution",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T23:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "512d7db8c61acf0cdf08f4260533ed3c14ffd30b",
          "body": null,
          "is_bot": false,
          "headline": "Add .playwright-mcp/ to .gitignore",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T22:37:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb17a79bbf3944092c6c3879c206fd0a2b6b080d",
          "body": null,
          "is_bot": false,
          "headline": "Add .gambit/ to .gitignore",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T22:33:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "183d824332d859e5da0d94b64d969947c4ecc054",
          "body": "Validates --geo-id before hitting the API. Detects common wrong\nformats (ZIP_90210, CITY_*, COUNTY_*, STATE_*, ADDR_*) and tells\nthe agent exactly what to do: use bare zip/state codes, or resolve\nvia addresses search.",
          "is_bot": false,
          "headline": "Catch wrong geo_id prefixes with actionable error message",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T19:36:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1acf2d58b36677833e8b8fd8fb228f7323f1392c",
          "body": "Replace wrong formats (ZIP_90210, CITY_LOS_ANGELES_CA, etc.) with\ncorrect ones: bare zip codes (92024), state codes (CA), and opaque\nShovels IDs resolved via addresses search.\n\nAdd \"Geographic IDs\" section to permits search and contractors search\nhelp text explaining the two-step resolution workflow. Flag description\nnow includes the resolve command as a one-liner.",
          "is_bot": false,
          "headline": "Fix geo_id docs across all help text and README",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T19:33:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "06268f8dea6025a16ef306657e4d64ca313dc7a9",
          "body": "The install script is now hosted at the marketing site root.\n  curl -LsSf https://shovels.ai/install.sh | sh",
          "is_bot": false,
          "headline": "Update install URL to shovels.ai/install.sh",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T18:57:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "17ba7cb70cf44c8e6cdc32e454c57cba44dd947c",
          "body": "Zip codes use bare 5-digit codes (92024), states use 2-letter codes\n(CA). All other geographies (addresses, cities, counties) have opaque\nIDs that must be resolved via addresses search. Formats like\nCITY_LOS_ANGELES_CA do not exist.",
          "is_bot": false,
          "headline": "Document geo_id format rules in CLAUDE.md",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T18:39:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "03a41890dcd6de16a38d53d5d12f6ca78d6ed4cf",
          "body": "Remove Homebrew (not set up), go install (niche), manual download\ntable (redundant with install.sh). Tighten Quick start, Commands,\nOutput format, and reference sections. 343 → 261 lines.",
          "is_bot": false,
          "headline": "Trim README to working sections only",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T17:22:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "12d64c28525cbe1fabac0bf7d1cd828b92febfef",
          "body": "Promoted as the first install option — one command, no prerequisites\nbeyond curl and tar. Downloads latest release, verifies checksum,\ninstalls to ~/.shovels/bin, adds to PATH.",
          "is_bot": false,
          "headline": "Add curl | sh quick install to README",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T17:20:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23a975d6a383ff4f3274d4bb6543435f634518e8",
          "body": "Detects OS/arch, downloads from GitHub Releases, verifies SHA256\nchecksum, installs to ~/.shovels/bin, and appends to PATH in the\nuser's shell profile. Supports GITHUB_TOKEN for private repos.",
          "is_bot": false,
          "headline": "Add curl | sh install script",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T17:17:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "74bdb31de021326e280930c02d5d3c2e22b376d1",
          "body": "- Remove .spade/ from git (internal tooling state, Linear URLs, local paths)\n- Remove Linear tracking link from CLAUDE.md\n- Replace staging.shovels.ai with example.com in help text and README\n- Add .spade/, worktrees/, .env, *.pem, *.key to .gitignore",
          "is_bot": false,
          "headline": "Remove internal references and harden .gitignore before going public",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T17:17:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ff1d8084d6959593170621f2c58ff2400ad01853",
          "body": "Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.9 to 1.0.10.\n- [Release notes](https://github.com/spf13/pflag/releases)\n- [Commits](https://github.com/spf13/pflag/compare/v1.0.9...v1.0.10)\n\n---\nupdated-dependencies:\n- dependency-name: github.com/spf13/pflag\n  dependency-version: 1.0.10\n  dependency-type: direct:production\n  update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Bump github.com/spf13/pflag from 1.0.9 to 1.0.10",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-02T17:03:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aa0436bc548acfad733c66fac5efa960d09e0300",
          "body": "Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.\n- [Release notes](https://github.com/actions/setup-go/releases)\n- [Commits](https://github.com/actions/setup-go/compare/v5...v6)\n\n---\nupdated-dependencies:\n- dependency-name: actions/setup-go\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/setup-go from 5 to 6",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-02T17:03:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "558a3d12212525d7520a30280d656240092df972",
          "body": "Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.\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/v4...v6)\n\n---\nupdated-dependenc\n[…]\n:\n- dependency-name: actions/checkout\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/checkout from 4 to 6",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-02T17:03:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "59ffc8a497f5115fe1a856af80884eab0a74bae5",
          "body": "Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 6 to 7.\n- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)\n- [Commits](https://github.com/goreleaser/goreleaser-action/compare/v6...v7)\n\n---\nupdated-dependencies:\n- dependency-name: goreleaser/goreleaser-action\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 goreleaser/goreleaser-action from 6 to 7",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-02T17:01:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f9327c504dded047c7136c9c8e1dac20a07d1067",
          "body": "Comment out Homebrew tap config until tap repo and secret are ready.\nFix release owner casing to ShovelsAI. Re-add release badge to README.",
          "is_bot": false,
          "headline": "Prepare for v0.1.0 release",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T16:40:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7ac1ade1eb08eecd0485883c1a4dddd7fa7a1f7",
          "body": "Capitalize title to \"Shovels CLI\". Fix CI badge org casing to match\nactual GitHub org (ShovelsAI). Remove release badge until first tag\nis pushed.",
          "is_bot": false,
          "headline": "Fix README title and badge URLs",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:46:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21e1d9c687dc8bacfa6c64324ed43b18c89b7ea6",
          "body": "…arch\n\nRestored from the original README — documents that --include-count\nreturns total_count (capped at 10,000) in the meta envelope.",
          "is_bot": false,
          "headline": "Add --include-count optional flag docs for permits and contractors se…",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:44:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "855ac79efbe00cda1dcb6692f7de384612e4d462",
          "body": "Bug report and feature request issue templates. Weekly Dependabot\nupdates for Go modules and GitHub Actions dependencies.",
          "is_bot": false,
          "headline": "Add GitHub issue templates and Dependabot config",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:43:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "22cebb20f03ef47b47d8f08f52f5a7c078d5eaf9",
          "body": "Badges: CI status, latest release, Go Report Card, MIT license.\nNew sections: \"What is this\" value prop, command tree overview for\nLLM scanning, stderr error format with error_type values, platform\ntable for binary downloads, API reference link.",
          "is_bot": false,
          "headline": "Add production README with badges and agent-friendly structure",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:43:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83a6ff3c0e05d6af8b619d82b29dc57f2c8d99b9",
          "body": "Copyright 2025 Shovels, Inc. Unblocks the license badge in the\nREADME and the Homebrew formula license field in GoReleaser.",
          "is_bot": false,
          "headline": "Add MIT license",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:43:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2cbd46a3b786acabdf4c204f2d60d72293cfcc34",
          "body": null,
          "is_bot": false,
          "headline": "Fix gofmt trailing newline in config_test.go",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "29d530014e0f859ee60bef5c8457263c2f69e82d",
          "body": "Search endpoints can request server-side result counts via the API's\ninclude_count parameter. The count is capped at 10,000 and only\nreturned on the first page of results.",
          "is_bot": false,
          "headline": "Add --include-count flag for total result counts",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "73d4677b7453dc7a4dbb140a16c6d14791569138",
          "body": null,
          "is_bot": false,
          "headline": "Populate version commit and date from git for local builds",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e22ac06f97b5b3b3a6bb0a130c8ffdf18f818e8",
          "body": null,
          "is_bot": false,
          "headline": "Update go.mod and SPADE state",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cdb809d4e51c5cb91cc8fa341db6ba9faaff80f5",
          "body": "- Add missing exit code 5 (transient/server error) to design principles\n- Fix envelope format docs to match actual {data, meta} structure\n- Add .gitignore for build artifacts, .envrc, and IDE files",
          "is_bot": false,
          "headline": "Fix stale CLAUDE.md docs and add .gitignore",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7cdb4c50fd4cd48cc46f25fd16d3700a174ff177",
          "body": "Security improvement: remove --api-key CLI flag since passing secrets\nvia command-line arguments exposes them in process lists. Auth now\nresolves via SHOVELS_API_KEY env var or config file only.\n\nAdd --version flag via cobra's built-in version support, enabled by\nsetting rootCmd.Version in SetVersionInfo.\n\nUpdate all e2e tests to use env-based auth (withIsolatedConfig sets\nSHOVELS_API_KEY=sk-test, withIsolatedConfigNoAuth clears it) and\nremove all --api-key flag references from test invocations.",
          "is_bot": false,
          "headline": "Remove --api-key flag and add --version support",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b9dd312da711ea9ba240d9a878e317a54ee39d6",
          "body": "The API parameters are permit_from and permit_to on both\npermits and contractors search endpoints. Aligning flag\nnames with API parameters removes ambiguity about what\ndate range is being filtered.",
          "is_bot": false,
          "headline": "Rename --from/--to to --permit-from/--permit-to",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ceb6568da952f297bd24e5f4e5553d48bb222eb",
          "body": "The API serves address search at /addresses/search, not\n/addresses. Incorrect path caused 404 responses for all\naddress queries.",
          "is_bot": false,
          "headline": "Fix addresses search endpoint path",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3d4d562a6058bd0931e5b12f9e92ddfa94d4adf8",
          "body": "Users and AI agents need a single document covering\ninstallation, authentication setup, and available commands\nto get started without reading source code.",
          "is_bot": false,
          "headline": "Add README with install and command reference",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95c3652d3ae7cf67e24fa97f817053253e9aaf42",
          "body": "Multi-platform distribution requires automated build and\nrelease pipelines triggered by git tags. CI validates every\npush and pull request before code reaches main.",
          "is_bot": false,
          "headline": "Add GoReleaser and GitHub Actions workflows",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "98f66ff2bb2ddf88cf9ecad15668dd661aa72243",
          "body": "Full command surface coverage for plain-text and exit-0 assertions\nprevents help regressions across all subcommands. Default value\nassertions ensure global flag documentation stays accurate.",
          "is_bot": false,
          "headline": "Expand help e2e test coverage",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "837e81e4c5250b5da0dbe145ff44ba15a12b23e0",
          "body": "Help text is the primary documentation for AI agents consuming\nthis CLI. Descriptions use concrete language with example values\nand format hints so agents can construct valid commands without\ntrial and error.",
          "is_bot": false,
          "headline": "Add LLM-optimized help text for all commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bf257d90ce69cc76c2a53179cc68e020b7452fb1",
          "body": "Address search and credit usage checking complete the v1\nresource command set. Address search is paginated with a\nquery parameter; usage is a non-paginated single-object\nendpoint for account credit introspection.",
          "is_bot": false,
          "headline": "Add addresses search and usage commands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6fd40c1f27aa1f79261883614566c4ac6ee4a5be",
          "body": "Cobra's ExactArgs(1) validator rejects zero or multiple positional\narguments at the framework level, preventing silent ignore of extra\nargs that violated the single-ID contract.",
          "is_bot": false,
          "headline": "Enforce exact arg count on contractor subcommands",
          "author_name": "Luka Kacil",
          "author_login": "lknix",
          "committed_at": "2026-03-02T15:08:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 10,
      "commits_last_year": 135,
      "latest_release_at": "2026-07-17T16:00:07Z",
      "latest_release_tag": "v0.7.1",
      "releases_from_tags": false,
      "days_since_last_push": 2,
      "active_weeks_last_year": 5,
      "days_since_latest_release": 4,
      "mean_days_between_releases": 15.2
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 0,
      "stars": 9,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 3
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "go.mod"
      ],
      "largest_source_bytes": 83253,
      "source_files_sampled": 85,
      "oversized_source_files": 1,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 5541
    },
    "dependencies": {
      "manifests": [
        "go.mod"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "go"
      ],
      "dependencies": [
        {
          "name": "github.com/creativeprojects/go-selfupdate",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.5.2"
        },
        {
          "name": "github.com/spf13/cobra",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.10.2"
        },
        {
          "name": "github.com/spf13/pflag",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.0.10"
        },
        {
          "name": "gopkg.in/yaml.v3",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v3.0.1"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 3,
        "merged_prs": 12,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "lknix",
          "commits": 131,
          "avatar_url": "https://avatars.githubusercontent.com/u/954612?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "release.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 3,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "6 out of 6 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/9 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 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": "12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "15 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "18e79b023de69c64705b3ad9f9548e583a8270be",
        "ran_at": "2026-07-22T11:29:16Z",
        "aggregate_score": 4.3,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-20T03:14:51Z",
      "oldest_open_prs": [
        {
          "number": 12,
          "created_at": "2026-06-22T03:13:34Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 13,
          "created_at": "2026-07-13T03:14:15Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 15,
          "created_at": "2026-07-20T03:14:50Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-17T15:57:18Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/ShovelsAI/shovels-cli",
    "host": "github.com",
    "name": "shovels-cli",
    "owner": "ShovelsAI"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 51,
      "inputs": {
        "security": 43,
        "vitality": 77,
        "community": 31,
        "governance": 45,
        "engineering": 53
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 77,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "commits_last_year": 135,
              "human_commit_share": 0.96,
              "days_since_last_push": 2,
              "active_weeks_last_year": 5
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 2 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "5/52 weeks with commits",
                "points": 3.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "135 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 135
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 10,
              "latest_release_tag": "v0.7.1",
              "releases_from_tags": false,
              "days_since_latest_release": 4,
              "mean_days_between_releases": 15.2
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "10 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~15.2 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 15.2
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 31,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 15,
            "inputs": {
              "forks": 0,
              "stars": 9,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "9 stars",
                "points": 14.6,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 9
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 45,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 13,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 72,
            "inputs": {
              "merged_prs": 12,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "12/12 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 12,
                      "decided": 12
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/9 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 56,
            "inputs": {
              "followers": 14,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "ShovelsAI",
              "public_repos": 4,
              "account_age_days": 3978
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "14 followers of ShovelsAI",
                "points": 8.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 14,
                      "login": "ShovelsAI"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "4 public repos, account ~10 yr old",
                "points": 17.1,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 4
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 10
                    }
                  }
                ],
                "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": 53,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "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": "6 out of 6 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "at_risk",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 30,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 43,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 43,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 4.3
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection is not maximal on development and all release branches",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "6 out of 6 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/9 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "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": "12 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "15 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 1
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 78,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.906,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 5541
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "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": "87 of 96 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 87,
                      "sampled": 96
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 64,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "go.mod"
              ],
              "dependency_bot_commit_share": 0.04
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "go.mod (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "go.mod"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "Go (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "4 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 4,
                      "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": 99,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 83253,
              "source_files_sampled": 85,
              "oversized_source_files": 1
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "1/85 source files over 60KB",
                "points": 54.4,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 85,
                      "oversized": 1
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "Could not fetch go package 'github.com/shovels-ai/shovels-cli' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T11:29:30.705561Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/s/ShovelsAI/shovels-cli.svg",
  "full_name": "ShovelsAI/shovels-cli",
  "license_state": "standard",
  "license_spdx": "MIT"
}

评分是信号,而非担保。 评分反映的是 GitHub 上公开可见的实践——不是代码审计,也不是安全保证。

缺失数据将被剔除并重新归一化权重,绝不按零分计。方法论已版本化并公开:指标 v1.13.0、模式 v0.26.0—— 完整方法论 · 指标知识库.

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