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

whitworth-org / bedrock

CLI auditor for fundamental domain security controls

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

whitworth-org/bedrock 的健康指数为 100 分中的 59 分,处于「中等」区间。 其得分最高的类别是Vitality(77/100),最低的是Community & Adoption(24/100)。 最近一次更新在 4 天前。 近期的大部分工作由 1 位贡献者完成。

59
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

0 关注者3 个公开仓库始于 2020年4月

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

软件包生态系统

注册表软件包版本月下载量版本数最近发布
Gogithub.com/whitworth-org/bedrockv1.2.1-74 天前

按类别列示的指标

活力

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

77良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 4 天前
5.5/36提交节奏 — 52 周中有 8 周有提交
16.1/18提交量 — 最近一年 61 次提交
10/10OpenSSF Scorecard:Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year61
human_commit_share1
days_since_last_push4
active_weeks_last_year8

发布纪律

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

社区与采用

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

24危急 · 占总体的 18%
评分方式
0/60星标 — 0 个星标
0/25复刻 — 0 个复刻
0/15关注者 — 0 位关注者
所用输入
forks0
stars0
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

可持续性与治理

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

52中等 · 占总体的 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
评分方式
46.8/46.8议题解决 — 100% 的议题已关闭
20.6/38.3PR 接受 — 已裁定的 PR 中 28/52 已合并
0/15OpenSSF Scorecard:Code-Review — Found 0/21 approved changesets -- score normalized to 0
所用输入
merged_prs28
open_issues0
closed_issues1
issue_closed_ratio1
closed_unmerged_prs24
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
0/25所有者影响力 — whitworth-org 有 0 位关注者
16.4/25既往记录 — 3 个公开仓库,账户约 6 年
所用输入
followers0
owner_typeOrganization
is_verified
owner_loginwhitworth-org
public_repos3
account_age_days2,289
评分方式
25/25已发布且可解析 — go 上有 1 个软件包
35/35发布时效 — 最近一次发布于 4 天前
20/20版本历史 — 7 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagesgithub.com/whitworth-org/bedrock
ecosystemsgo
any_deprecated
min_days_since_publish4

工程质量

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

70良好 · 占总体的 20%

工程实践

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

文档

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

安全

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

71良好 · 占总体的 16%

安全态势

67中等
评分方式
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 — 21 out of 21 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/21 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
5/5Fuzzing — project is fuzzed
2.5/2.5许可证 — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
4/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 8
4.5/5SAST — SAST tool is not run on all commits -- score normalized to 9
5/5Security-Policy — security policy file 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
6.8/7.5Vulnerabilities — 1 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate6.7
评分方式
26.6/35直接依赖不含已知公告 — 1 个受影响:golang.org/x/crypto v0.54.0 (unknown)
0/25间接依赖不含已知公告 — 在此范围内,传递依赖集合无法与开发和测试依赖区分
40/40没有长期未处理的公告 — 没有公告公开超过 90 天
所用输入
sourceosv
advisories1
affected_packages1
assessed_packages10
unassessed_packages0
affected_by_severityunknown 1
direct_affected_packages1
已排除计分(无数据或不适用):间接依赖不含已知公告。 其余权重已重新归一化。 已将 10 个已解析依赖与 OSV 比对。 该仓库未发布任何索引可解析的软件包,因此改为评估仓库依赖图。该图将开发与测试版本固定同交付的依赖混在一起,因此仅对声明的运行时依赖计分;传递性发现仅作为背景信息列出,不计入评分。 未对可达性进行分析。

AI 就绪度

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

72良好 · 占总体的 0%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 61 次人类提交中有 60 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.984
agent_instruction_files
agent_instruction_max_bytes
评分方式
18/18一条命令的引导启动 — Makefile
22/22自动化测试
11/11Lint / 格式化配置 — .golangci.yml
11/11静态类型检查 — Go(静态类型)
10/10可复现环境 — lockfile
0/10已体现的代理实践 — 最近 61 次提交中没有代理编写的提交
5/8自动化维护 — 已配置依赖自动化,但在抽样提交中未观察到
8/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 8
所用输入
has_nix
has_tests
lockfilesgo.sum
has_dockerfile
typed_language
bootstrap_filesMakefile
has_devcontainer
has_linter_config
typecheck_configs
agent_commit_share0
toolchain_manifestsgo.mod
dependency_bot_commit_share0
评分方式
45/45可类型检查的代码 — Go(静态类型)
55/55可控的文件大小 — 采样的 139 个源文件中有 0 个超过 60KB
所用输入
primary_languageGo
largest_source_bytes47,924
source_files_sampled139
oversized_source_files0

关键数据

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

更多细节

OpenSSF Scorecard 6.7 / 10
6.7综合

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

10Binary-Artifactsno binaries found in the repo
3Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests21 out of 21 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/21 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
10Fuzzingproject is fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
8Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 8
9SASTSAST tool is not run on all commits -- score normalized to 9
10Security-Policysecurity policy file detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
9Vulnerabilities1 existing vulnerabilities detected
直接依赖 4
注册表软件包版本约束清单文件
Gogithub.com/miekg/dnsv1.1.72go.mod
Gogithub.com/quic-go/quic-gov0.60.0go.mod
Gogolang.org/x/cryptov0.54.0go.mod
Gogolang.org/x/netv0.57.0go.mod
全部依赖 10

来自 GitHub 依赖图的完整解析依赖集合:4 个直接依赖与 6 个间接(传递)软件包。仓库提交锁文件时,传递闭包才是完整的。

注册表软件包版本关系
Gogithub.com/miekg/dnsv1.1.72直接
Gogithub.com/quic-go/quic-gov0.60.0直接
Gogolang.org/x/cryptov0.54.0直接
Gogolang.org/x/netv0.57.0直接
Gogithub.com/quic-go/qpackv0.6.0间接
Gogolang.org/x/modv0.37.0间接
Gogolang.org/x/syncv0.22.0间接
Gogolang.org/x/sysv0.47.0间接
Gogolang.org/x/textv0.40.0间接
Gogolang.org/x/toolsv0.47.0间接
依赖安全公告 1

该仓库未发布可被索引解析的包,因此评估的是其自身的依赖图——共 10 个包,其中也包含从不交付的开发与测试版本固定:1 个存在已知公告,1 个为直接依赖。

软件包版本关系严重程度公告数修复版本
golang.org/x/cryptov0.54.0直接未知1

公告表示依赖图中记录的版本落入某条公告的受影响范围。可达性未经分析,且依赖图包含开发与测试的版本固定——某项发现可能只涉及工具链而非交付的软件。

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 767,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Go": 720051,
        "Makefile": 1354
      },
      "pushed_at": "2026-07-17T19:04:18Z",
      "created_at": "2026-04-17T22:48:15Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-17T05:42:12Z",
      "description": "CLI auditor for fundamental domain security controls",
      "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://whitworth.org",
      "name": "whitworth.org",
      "type": "Organization",
      "login": "whitworth-org",
      "company": null,
      "location": "Switzerland",
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/63663598?v=4",
      "created_at": "2020-04-14T16:55:45Z",
      "is_verified": null,
      "public_repos": 3,
      "account_age_days": 2289
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v1.2.1",
          "kind": "patch",
          "published_at": "2026-07-17T05:49:17Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2026-07-16T23:28:22Z"
        },
        {
          "tag": "v1.1.1",
          "kind": "patch",
          "published_at": "2026-07-02T02:07:32Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-04-29T22:15:01Z"
        },
        {
          "tag": "v1.0.2",
          "kind": "patch",
          "published_at": "2026-04-17T23:36:49Z"
        },
        {
          "tag": "v1.0.1",
          "kind": "patch",
          "published_at": "2026-04-17T23:24:01Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "6cd543d0d9cba8109e46a1b6e0683377167d7564",
          "body": null,
          "is_bot": false,
          "headline": "docs: bump man page version to 1.2.1 (#53)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-17T05:42:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "60bf25c0c628965297d650185930f4ad5d2eb541",
          "body": "The outbound User-Agent's +URL comment pointed at example.invalid, an\nRFC 2606 reserved domain that resolves nowhere — a scaffold placeholder\ncarried verbatim through the #38 centralization. The comment URL exists\nso operators of probed hosts can identify the client; point it at the\npublic repositor\n[…]\ning both a resolved version and the dev fallback,\nclosing the AI code-quality finding that the trailing URL component\nwas never validated. Verified the assertion fails against the old\nplaceholder URL.",
          "is_bot": false,
          "headline": "fix: point User-Agent comment URL at the repository (#52)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-17T05:01:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "340ebebd29dabbbdae73954fe52cbb473c2b374a",
          "body": "setup-go resolves range specs like 1.26.x from the runner's local tool\ncache without consulting the version manifest. The macos-latest image\npool currently caches only Go 1.26.4, which GOTOOLCHAIN=local (a\ndeliberate supply-chain guard we keep) rejects against go.mod's 1.26.5\nrequirement — so jobs p\n[…]\ne exact\nrelease go.mod requires, on every runner, deterministically. The test\nmatrix and job names are unchanged to preserve required-check names.\n\nactionlint clean; zizmor findings identical to main.",
          "is_bot": false,
          "headline": "ci: pin Go toolchain via go-version-file instead of 1.26.x range (#51)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-17T04:55:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a3999c61358dec476c13a5a155905454bcb920e5",
          "body": "readDMARC now honors its documented contract: a DMARC-shaped struct\nwith no Pct field defaults to 100 instead of tripping the pct gate.\nGet reports the insecure diagnostic retry's failure alongside the\noriginal chain error instead of discarding it. DoStrict applies the\nshared redirect policy (8-hop \n[…]\nreviously left at Go defaults. GetStrict drops its never-appended\nchain variable. The below-threshold retransmit test budget rises from\n500ms to 2s so slow CI cannot miss the single-attempt assertion.",
          "is_bot": false,
          "headline": "fix: address AI code-quality findings in probe and BIMI gate (#50)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-17T00:22:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f7f90aebc6a5eede50fd0afede4867957e048461",
          "body": "Implement RFC 9989 DMARC policy discovery via the DNS tree walk (max 8\nqueries, replaces the Public Suffix List): email.dmarc.record now\nevaluates subdomains against the organizational record they inherit,\nflags retired tags (pct/rf/ri), and applies t=y policy step-down. New\nchecks: email.dmarc.disc\n[…]\ne.\n\nAdd tree-walk/org-domain/parser unit tables, canned-DNS run tests,\ncache-injection tests, and three fuzz targets; fix the Makefile fuzz\nloop, which refused packages with more than one fuzz target.",
          "is_bot": false,
          "headline": "feat: DMARCbis tree walk, DKIM2 readiness, RFC 9990/9991 checks (#49)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-16T23:00:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "409677d16711fdbd108686a3d5829c72152c1611",
          "body": null,
          "is_bot": false,
          "headline": "build(deps): Go 1.26.5, x/crypto 0.54, x/net 0.57, action pins (#48)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-16T22:22:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "229adc6f39378bee4dcfad21eb9526d248311bb7",
          "body": "* fix: retransmit idempotent DNS queries once within budget\n\nA single dropped UDP datagram or a transiently throttled resolver\nconsumed the whole per-operation budget and surfaced as a spurious\nlookup FAIL. When --timeout is >= 4s, split the budget into two\nattempts of d.timeout/2 and retransmit onc\n[…]\n report Info (\"DMARC not parsed\") instead of the real verdict.\nExport email.EnsureDMARC and register the gate behind a dmarcPrelude\nthat primes it first, mirroring the existing ensureDMARC/np pattern.",
          "is_bot": false,
          "headline": "fix: DNS retransmit and BIMI Gmail-gate DMARC race (#42)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-03T08:54:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b355447563ba2ef4bd190d6ca034067562152da5",
          "body": "Address Copilot review findings on internal/probe/http.go:\n\n- Raise the base (verified) transport MinVersion from TLS 1.0 to TLS 1.2;\n  this client's responses may be trusted (bodies parsed), so it should meet\n  the modern baseline. Legacy servers stay inspectable via the TLS-profile\n  check and Get\n[…]\nithClient and avoid aliasing\n  net/http's header map.\n- Document the diagnostic insecure-retry path's TLS-relaxation tradeoff\n  explicitly (TLS 1.0 + InsecureSkipVerify; body untrusted and discarded).",
          "is_bot": false,
          "headline": "fix: raise HTTP client to TLS 1.2, clone fetch response headers (#41)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-02T04:32:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0f6cfb816a5fea7ad6041b97a2dc0c4933de1085",
          "body": "TestStringWithCommitOnly rendered \"(short)\" or \"(short <date>)\" depending\non whether `go test` stamped vcs.time into the test binary, and only\nt.Logf'd on mismatch. Add a readBuildInfo seam over debug.ReadBuildInfo so\nthe fallback can be driven explicitly: one case forces (nil,false) and\nasserts the\n[…]\n and\nasserts the date is appended.\n\nAlso use an obviously-synthetic epoch date in TestStringWithCommitAndDate\ninstead of a real-looking one; the value is a test-controlled input, not a\nreal timestamp.",
          "is_bot": false,
          "headline": "test: make version BuildInfo fallback deterministic (#40)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-02T04:32:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "720d25971b944d46764e76e317e59ad02fa6c909",
          "body": "… (#39)\n\nThe WWW cert check rebuilt its TLS state on a cache miss via env.HTTP.Get,\nwhich follows redirects: a host that 301s elsewhere (e.g. apex -> www of\nanother brand) returned the redirect target's certificate, then validated\nit against the original host — a false-positive SAN/chain FAIL. The c\n[…]\nState). It speaks no HTTP, so a redirect cannot divert cert\ninspection; probe.VerifyChain still performs the real chain/hostname check\nagainst the target. Drop Response.CertChainError, now write-only.",
          "is_bot": false,
          "headline": "fix: inspect target's own cert on TLS cache miss, not redirect target…",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-02T03:44:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c34efdacb74d3058df00324cd45670173abbb3d1",
          "body": "Replace the four hardcoded \".../0.1\" User-Agent literals with\nversion.UserAgent(), derived from the ldflags-injected build version\nthrough the same resolver as --version. Release builds now identify as\nthe real version (e.g. 1.1.1) rather than the stale 0.1; local builds\nreport .../dev.\n\nRemove the dead ctUserAgent constant: CT requests already carry the\nUser-Agent set by probe.fetch.",
          "is_bot": false,
          "headline": "refactor: centralize outbound User-Agent in internal/version (#38)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-02T02:35:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ace4b2f929b723b63b650c6c1708271cd545495",
          "body": "- Reword the SSRF sentence: the client blocks denylisted address ranges.\n- Note the passive subdomain sources are third-party services and that\n  querying them may disclose investigation targets.\n- Document why the hostname allowlist permits underscores (service labels\n  such as _dmarc); it is an injection-safety filter, not RFC 1123.\n- List NO_COLOR in the ENVIRONMENT section.\n- Bump .TH to bedrock 1.1.1 / 2026-07-02 for the release.",
          "is_bot": false,
          "headline": "docs: address man-page review findings; bump to 1.1.1 (#37)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-02T02:04:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3711cbc96538d6e3946528840ffedbcd6358e04d",
          "body": "- actions/checkout 6.0.3 -> 7.0.0 (raptor lock workflows)\n- actions/setup-go 6.4.0 -> 6.5.0 (ci, release)\n- github/gh-aw-actions/setup 0.79.8 -> 0.81.4 (raptor lock workflows)\n\nSupersedes #33, #34, #35.",
          "is_bot": false,
          "headline": "build(deps): bump CI action pins (#36)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-07-02T01:59:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "71cf45388da10c8528262a08c4691dcae0bf4b6d",
          "body": null,
          "is_bot": false,
          "headline": "Install kite security review workflow (#32)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-06-24T01:37:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "94ad4d653d96dd2695b7d3d83d9c8f7614e3d84a",
          "body": "The man page documented flags and output behavior that no longer match\nmain.go.\n\n- Remove the non-existent --json / --md flags; document the real\n  --no-color flag.\n- Rewrite OUTPUT: the tool always emits JSON (ANSI-highlighted on a TTY\n  unless --no-color / NO_COLOR), not a text or Markdown report.\n- Drop --json from the jq, file-output, and CI examples.\n- Bump the .TH version to 1.1.0 and use an ISO date.",
          "is_bot": false,
          "headline": "docs: align man page with the current CLI (#31)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-06-18T17:40:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d27335b0556a6ef1cd0685fee38abaad11b64bb9",
          "body": "Parse and evaluate the externally observable RFC 9989 (obsoletes\nRFC 7489) tags in a published _dmarc record.\n\n- Extend the DMARC parser: np, psd, t, and fo tags; resolve the\n  np<-sp<-p inheritance chain; mark pct= as deprecated.\n- Add the email.dmarc.np check: PASS on np=reject, WARN on\n  quaranti\n[…]\n reliably under the parallel registry instead of racing the\n  email.dmarc.record producer.\n- Re-cite RFC 7489 -> RFC 9989 in the DMARC, ARC, and BIMI Gmail\n  gate checks, the README, and the man page.",
          "is_bot": false,
          "headline": "feat: add RFC 9989 (DMARCbis) DMARC coverage (#30)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-06-18T17:30:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "10e8dd8de4d23563bada4533b02e68e7f703dd88",
          "body": "- golang.org/x/net 0.55.0 -> 0.56.0 (supersedes #28)\n- golang.org/x/mod 0.36.0 -> 0.37.0\n- golang.org/x/tools 0.45.0 -> 0.46.0\n- actions/checkout v6.0.3 -> v7.0.0 (pinned SHA)",
          "is_bot": false,
          "headline": "build(deps): update modules to latest and refresh CI pins (#29)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-06-18T17:29:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f8adcefd30c4ee73c6430cf708890a988f103fc",
          "body": "* build(deps): bump quic-go 0.60.0, x/crypto 0.53.0, x/net 0.55.0\n\nResolves CVE-2026-40898 (quic-go HTTP/3 QPACK trailer memory exhaustion,\nfixed in 0.59.1) and GO-2026-5026 (reachable x/net/idna vulnerability, fixed\nin 0.55.0). Indirect dependencies updated via go mod tidy.\n\n* ci: bump pinned actio\n[…]\nt 6.0.2->6.0.3, golangci-lint-action 9.2.0->9.2.1,\ngoreleaser-action 7.1.0->7.2.2. Pin govulncheck install (was @latest) for\nreproducible scans; the vulnerability database is still fetched at runtime.",
          "is_bot": false,
          "headline": "build(deps): update modules to latest and refresh CI pins (#27)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-06-08T22:24:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e6ce2ee51f17c4c540af848bfa884d3e9398db1f",
          "body": "feat: native JA3S/JA4S TLS server fingerprinting",
          "is_bot": false,
          "headline": "Merge pull request #19 from whitworth-org/feat/tls-fingerprinting",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:27:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0c5aae71d3b3db5ed5d2917df70e099d7e69cc45",
          "body": "…limitation\n\nThe Limitations bullet on JA3S/JA4S had grown into a feature-description\nparagraph; pared back to the actual remaining limit (no client-side\nfingerprint emitted). Output and Subdomain Discovery sections rewritten\nfor density without losing precision; em-dashed parentheticals replaced\nwith parens so they don't read as AI-generated.",
          "is_bot": false,
          "headline": "docs: simplify README — tighten output/subdomain sections, prune JA3 …",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:21:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "29981770f662afc0ac740d3776996cd0f3168d6d",
          "body": "Adds a fingerprintHosts pass that runs alongside the existing TLS\nreachability pass when --subdomains is on, emitting INFO results\nsubdomain.tls.fingerprint.ja3s.<host> and ...ja4s.<host> for every\ndiscovered host whose handshake succeeds. Concurrency is bounded by the\nsame maxConcurrentDials cap pr\n[…]\nNewTLSServer end-to-end without binding\n:443 or relying on outbound network. Production always targets :443.\n\nREADME updated to mention the new IDs in the Subdomain section and the\nLimitations bullet.",
          "is_bot": false,
          "headline": "discover: fan out JA3S/JA4S fingerprints across discovered subdomains",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:21:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0e5eae3d95e6d71167fdf252b1439c5fecbec007",
          "body": "Documents the two new fingerprint check IDs in the Web/TLS table and\nadds internal/probe/tlsfp/ to the project layout. Rewrites the\n'JA3/JA4 not implemented' limitation to describe the native ServerHello\ncapture instead.\n\nAlso catches up on workstream B fallout: drops --json/--md flags,\ncollapses the Text/JSON/Markdown sections to JSON-only, removes Markdown\nreferences in quick-start and CI examples, and fixes the report\nrenderer description in the project layout.",
          "is_bot": false,
          "headline": "docs: refresh README for JSON-only output and JA3S/JA4S checks",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:21:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5dfb9a04f5b9b880c35d1a4da39130d6f1d66cfc",
          "body": "Adds web.tls.fingerprint.ja3s.<host> and web.tls.fingerprint.ja4s.<host>\nas INFO-status results so they surface as observational evidence\nwithout polluting pass/fail. Both registrations iterate the same apex+www\nhost set used by web.tls.profile (candidateHosts) and dial through the\nSSRF-safe dialer.\n[…]\nt check to run for a given host caches its\n*tlsfp.Result on env so the sibling check reuses it without a second\nhandshake.\n\nRefreshes the empty.json golden fixture to include the two new INFO\nentries.",
          "is_bot": false,
          "headline": "checks/web: register JA3S and JA4S fingerprint checks",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:21:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e1b817f9958e1abfb30c2a9f84743d9b41d3df05",
          "body": "Captures cleartext ServerHello bytes during a stdlib crypto/tls handshake\nvia a recordingConn net.Conn wrapper, then parses the RFC 5246 / RFC 8446\nServerHello layout with bounds-checked byte slicing — no third-party\nTLS, fingerprint, or hashing dependencies.\n\nJA3S follows Salesforce's 2017 spec (md\n[…]\n package can route through the\nexisting SSRF-safe dialer. Tests cover parser bounds, hash determinism,\norder sensitivity, ALPN normalisation, and an end-to-end handshake\nagainst httptest.NewTLSServer.",
          "is_bot": false,
          "headline": "probe: add native tlsfp package for JA3S/JA4S fingerprints",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:21:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "43cd3ed5205425e44c3ab560eff9d1cc7599a51e",
          "body": "security: SSRF, parser DoS, config hardening, HTTP keep-alives",
          "is_bot": false,
          "headline": "Merge pull request #18 from whitworth-org/feat/security-hardening",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:20:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c8cc20596c93d0af31297ead00b8618d33a818e4",
          "body": "Enable keep-alives for Get() and Do() methods to optimize back-to-back\nrequests to the same audited domain (HSTS root + paths, OCSP + responder,\netc.). DoStrict() and GetStrict() maintain disabled keep-alives for\nmaximum security posture.\n\nCompletes A4 post-integration follow-up.",
          "is_bot": false,
          "headline": "feat: enable HTTP keep-alives for per-target optimization",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:18:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d805cd9239ad150cc1ec785b4dedb48000f6598",
          "body": "Close three SSRF vulnerabilities by routing all HTTP through safeDialContext:\n- web/ct: crt.sh certificate transparency lookups\n- web/ocsp: OCSP responder and CRL distribution point fetches\n- discover: passive subdomain enumeration API calls\n\nAdd ASN.1 parser DoS protection caps to BIMI logotype dec\n[…]\nble tparallel linter for better test race detection\n- Update SSRF-affected tests to skip when protection blocks localhost\n\nAll changes maintain backward compatibility except enhanced input validation.",
          "is_bot": false,
          "headline": "security: comprehensive hardening pass (workstream C)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:15:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b3af5eed97c93216646bee2b792734bf68668304",
          "body": "registry: bounded parallel checks + checkutil migration",
          "is_bot": false,
          "headline": "Merge pull request #17 from whitworth-org/feat/registry-concurrency",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:14:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e6a6bfd6e394f957389108a80b9acdb4b0d2d028",
          "body": "BenchmarkRunCategoryParallel registers 16 stub checks that each sleep\n50 ms — a synthetic stand-in for I/O-bound real checks. With\nmaxChecksPerCategory=8 a single Run completes in ~100 ms (ceil(16/8) *\n50 ms); the pre-A1 sequential loop would have taken ~800 ms.",
          "is_bot": false,
          "headline": "registry: add parallelism benchmark for the new worker pool",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:11:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21b4c94314c99023b11a688d667a60d48ac7fa7f",
          "body": null,
          "is_bot": false,
          "headline": "checks/dnssec: gofmt trailing newline",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:11:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fe0ab32dfc6ec11d3104f0163cc1daa740b42f6b",
          "body": "Pre-A1 the registry ran category checks sequentially, so recordCheck\nalways populated the BIMI record cache before svgFetch / vmcFetch /\ngmailGate consumed it. Post-A1 the order is non-deterministic. A new\nprelude wrapper at registration time calls ensureRecord (a per-Env\nsync.Once around the TXT lo\n[…]\ny has graceful\ndegradation when those entries are missing.\n\nDoes not migrate bimi to checkutil.Wrap — that touches svg.go / vmc.go\n/ logotype.go which Workstream C owns; record.go and bimi.go are A's.",
          "is_bot": false,
          "headline": "checks/bimi: serialise TXT lookup with sync.Once for parallel registry",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:11:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9f7a6d402bed052a8e7d0372ca6b3758e45c5e49",
          "body": "Drops the empty-struct + ID/Category/Run boilerplate for tls, cert,\nredirect, hsts, headers, cookies, caa, mixedcontent, eccurve, http2,\nhttp3. web/ct.go and web/ocsp.go are left for Workstream C to migrate\nalongside their HTTP-client edits.",
          "is_bot": false,
          "headline": "checks/web: migrate non-C-owned registrations to checkutil.Wrap",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:10:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a48acaa3132f646f1dda704b79a934eb12c2ebd7",
          "body": "Drops the empty-struct + ID/Category/Run boilerplate for the twelve\nemail checks (spf, dkim, dmarc, mtasts.txt, mtasts.policy, tlsrpt,\ndane, nullmx, smtp.starttls, google_workspace_mx, arc, rbl). Run logic\nmoves into runXxx free functions; behaviour is unchanged.",
          "is_bot": false,
          "headline": "checks/email: migrate registrations to checkutil.Wrap",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:10:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "11aab6b20d44472babde5d9600007dfc8b7a4ae6",
          "body": "The four DNSSEC checks (chain, algorithms, nsec, cds) previously\ndepended on chainCheck running first to populate the per-Env cache with\nDS and DNSKEY records. Under the parallel registry that ordering no\nlonger holds. ensureChainData uses a per-Env sync.Once so the DS+DNSKEY\nqueries fire exactly on\n[…]\nhich would serialise\nevery other concurrent check's CacheGet/CachePut against our DNS\nround-trip.\n\nAlso drops the legacy empty-struct + ID/Category/Run shape in favour\nof checkutil.Wrap registrations.",
          "is_bot": false,
          "headline": "checks/dnssec: migrate to checkutil.Wrap; share DS+DNSKEY via Once",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:10:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f2c1c2161d695d1bdba160f62746c0b0bd6d3d77",
          "body": "Drops the empty-struct + ID/Category/Run boilerplate for the ten DNS\nchecks. Run logic moves into runXxx free functions that satisfy the\ncheckutil.RunFn signature; behaviour is unchanged.",
          "is_bot": false,
          "headline": "checks/dns: migrate registrations to checkutil.Wrap",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:10:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c33d1be55708f1f23e39045c045ad1d791ff7d8d",
          "body": "Inserts cancellation gates so a cancelled scan stops issuing the next\nnetwork request instead of pushing each remaining call through to its\ndeadline. Touched: dns/zone, dns/cnamehygiene, dns/dangling, email/dane,\nemail/dkim, web/tls, web/redirect.\n\nweb/{ct,ocsp} and bimi/{svg,vmc,logotype} are owned by Workstream C\nright now to avoid conflicts with their HTTP-client and parser-cap\nedits; gates there will land alongside C's changes.",
          "is_bot": false,
          "headline": "checks: add mid-flight ctx.Err() gates between independent round-trips",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:10:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "76ca0f2b763bc50abbfff60e3912f15da59873cf",
          "body": "New internal package collapses the empty-struct + ID/Category/Run shape\nthat almost every check repeats. Wrap returns a registry.Check-shaped\nvalue; RequireActive option auto-emits a NotApplicable result when\n--no-active is set; Timeout option applies env.WithTimeout. FailErr and\nFailCtx are canonical Result builders for lookup errors and mid-flight\nctx cancellation.\n\nMigration of existing checks happens in per-category follow-up commits.",
          "is_bot": false,
          "headline": "checks/checkutil: introduce Wrap helper + Fail{Err,Ctx} for boilerplate",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f540eee83acb0e940303844aa1126a8282f4115",
          "body": "Replaces the sequential inner loop in Run with a per-category bounded\nworker pool capped at maxChecksPerCategory=8. Panic-recover moves to\nthe per-check goroutine so one bad check no longer tanks its siblings.\nResult append remains under the existing mutex; final order is still\n(category, id).\n\nAdds a 100-check fan-out race test plus a sibling-isolation test.",
          "is_bot": false,
          "headline": "registry: bound per-check parallelism with semaphore worker pool",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T19:10:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8445a51c94ba40211fb8abcc46b7142afd30e9bb",
          "body": "Drop text and Markdown rendering in favor of JSON-only output.\nAdd ANSI syntax highlighting when stdout is a TTY.\n\n- Remove Format enum, renderText, renderMarkdown functions\n- Add RenderJSON with plain/colored paths\n- Add Status.UnmarshalJSON for round-trip compatibility\n- Drop --md and --json flags, add --no-color\n- Honor NO_COLOR environment variable\n- Sanitize all string fields to prevent ANSI injection\n- Update golden fixtures and integration tests",
          "is_bot": false,
          "headline": "refactor: JSON-only output with TTY coloring",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-29T18:59:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e43d27669263aff593963915b22fac61492fa158",
          "body": "Pinned to SHA e24998b (tag v7.1.0). Supersedes #11.",
          "is_bot": false,
          "headline": "ci: bump goreleaser/goreleaser-action to v7.1.0 (#12)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-26T15:52:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b6bb95e079ce1b0d6d463d99511074226c8aaf55",
          "body": "Re-format the existing WHY comment as a godoc-style doc comment so the\nGitHub AI-finding (\"function lacks a doc comment\") clears on rescan.\nFirst sentence describes behaviour exactly (no \"truncates\" handwave —\nthe function is conditional); the WHY about the 12-byte cap is preserved.",
          "is_bot": false,
          "headline": "docs: convert shortRev comment to godoc style",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-18T01:23:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5e8d88157136fc9a46fb03f471469712d9570802",
          "body": "README: drop AI tells in the lead paragraph, feature bullets, License,\nand Limitations sections. Rule-of-three framing, inline-bold category\nlists, and promotional intensifiers (\"fundamental\", \"Safe by default\")\nremoved. Technical precision unchanged; tables, code blocks, flag\nreference, and JSON schema untouched.\n\nSECURITY: drop boilerplate (\"are taken seriously\"), \"Please\" padding,\nand \"where applicable\" hedges. Report URL, supported-versions table,\nand SLA numbers unchanged.",
          "is_bot": false,
          "headline": "docs: humanize and tighten README and SECURITY policy",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-18T01:17:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "14acb62849ff4ffbaac6f4bb59e3d7f4a94b4846",
          "body": "Headings (DNS, DNSSEC, Email, BIMI, Web / TLS) now carry only the category\nname. Per-check RFC citations remain in the tables, where they are useful\non the row that cites them. BIMI also sheds its parenthetical and tail.",
          "is_bot": false,
          "headline": "docs: drop RFC suffixes from category headings",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-18T01:09:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3325a520ba654b6c81a5ea34a419c195f1143f24",
          "body": "The constant matches GitHub-style short SHAs and bounds the 40-char\nvcs.revision returned by runtime/debug.ReadBuildInfo (the ldflags path\nuses git rev-parse --short, which is shorter).",
          "is_bot": false,
          "headline": "docs: explain magic 12 in shortRev",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-18T01:09:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7ddf48e3aafdc5275f3402a58b91fb3896248470",
          "body": "- SECURITY.md: direct vulnerability reports to GitHub Private\n  Vulnerability Reporting; document supported versions, scope,\n  and response SLAs.\n- .github/CODEOWNERS: assign @rjwhitworth as default owner via\n  a single `*` rule; intentionally portable across whitworth-org\n  repositories.\n- .gitignore: carve out !SECURITY.md alongside the existing\n  !README.md exception so the policy file is tracked.",
          "is_bot": false,
          "headline": "docs: add SECURITY policy and portable CODEOWNERS",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-18T00:21:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0e112d4ef1ffd60bb7be7d5a5871a71f80f89ff8",
          "body": "Install surface:\n\n- README ## Install now leads with the recommended form:\n    go install github.com/whitworth-org/bedrock@latest\n  ...with a pinned variant, a \\$GOBIN / PATH note, and the from-source\n  and pre-built-binary paths kept as secondary options.\n\nVersion-string behaviour:\n\n- internal/vers\n[…]\n    go install @latest  → same as above\n\n  Previously \\`go install\\` binaries reported a stale \"bedrock 0.1.0-dev\"\n  regardless of which tag the proxy served.\n\nRace suite green across all 13 packages.",
          "is_bot": false,
          "headline": "bedrock: prefer \\`go install\\`; report real tag on module-proxy builds",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T23:34:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "56235c8d9ac1525c7088d8c781ecb7416ea8d766",
          "body": "Errcheck (real I/O sites):\n  internal/probe/http.go           (r.Body.Close)\n  internal/probe/doh.go            (resp.Body.Close)\n  internal/checks/web/http2.go     (rawConn.Close)\n  internal/checks/web/ct.go        (resp.Body.Close)\n\nErrcheck exclusions in .golangci.yml: fmt.Fprintf / fmt.Fprintln \n[…]\nest-only mkdir perms for golden fixtures\n  G306  test-only writefile perms for golden fixtures\nintegration_test.go tightened anyway: 0o755→0o750, 0o644→0o600.\n\nRace suite green across all 13 packages.",
          "is_bot": false,
          "headline": "bedrock: clear remaining lint findings under golangci-lint v2",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T23:06:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f35d0caccf0d01f3643934319034205192c64337",
          "body": "golangci-lint v2 (errcheck) now flags seven unchecked deferred .Close()\ncalls that the previous v1.64.x binary was not running against. Each\nsite is on a cleanup path where the Close() error is not actionable\n(an in-memory file after io.ReadAll, an HTTP body after the wire read,\nan SMTP textproto af\n[…]\n, *http.Response.Body)\n  internal/checks/web/ocsp.go     (*http.Response.Body x2)\n  internal/discover/sources.go    (*http.Response.Body)\n\nBehaviour unchanged; race suite green across all 13 packages.",
          "is_bot": false,
          "headline": "bedrock: silence errcheck on deferred Close()",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T22:59:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fbc08bab359f3e73180a0d13876394e4e34b78e1",
          "body": "Hardens the supply chain for CI and release workflows:\n\n- actions/checkout      v4      → v6.0.2 (SHA-pinned)\n- actions/setup-go      v5      → v6.4.0 (SHA-pinned)\n- golangci-lint-action  v6      → v9.2.0 (SHA-pinned)\n- goreleaser-action     v6      → v7.0.0 (SHA-pinned)\n\nThe golangci-lint binary is\n[…]\n)\n\nv9 of the action is required for v2 golangci-lint (the repo's\n.golangci.yml already declares schema \"version: 2\"). Dependabot will\ncontinue to bump both the SHA and the \"# vX.Y.Z\" comment together.",
          "is_bot": false,
          "headline": "ci: pin GitHub Actions to SHA; bump golangci-lint to v2.11.4",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T22:56:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "06befb098b901880ef084e0c4287f1a58908ea80",
          "body": "…agline\n\n- go.mod: module path → github.com/whitworth-org/bedrock\n- all internal imports, ldflags, Makefile, .goreleaser.yaml, README updated\n- README tagline + man NAME line re-worded to \"CLI auditor for\n  fundamental domain security controls\"",
          "is_bot": false,
          "headline": "bedrock: rename module to github.com/whitworth-org/bedrock; refresh t…",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T22:46:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a796f6ab61c04ba2ef44fb5f2f9f27a7202b2c9f",
          "body": "- README: full rewrite — every flag, every check ID organised by category\n  with RFC citations, output/JSON schema, exit codes, MIT recommendation\n  rationale, Hardenize credit\n- man/bedrock.1: remove granite-scan leftovers, document\n  BEDROCK_ALLOW_PRIVATE_RESOLVER, update RFC 3709 note to reflect \n[…]\n%),\n  version (4 tests, 81.8%)\n- smoke_test: replace hardcoded personal domain with env-var override\n  (BEDROCK_SMOKE_DOMAIN) defaulting to example.com, renamed\n  TestSmokeWhitworth -> TestSmokeDomain",
          "is_bot": false,
          "headline": "bedrock: docs refresh, Google Workspace MX check, test coverage",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T22:09:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0e211515960f9f19772a51b8920880c41a17310b",
          "body": "…+12)\n\n- Module rename: module bedrock -> github.com/rwhitworth/bedrock\n  (sweep imports across 68 files; go build / go vet / govulncheck / go test -race clean)\n- Add LICENSE (MIT)\n- Add .gitignore rule for /out/ (review/scan outputs)\n- BEDROCK_ALLOW_PRIVATE_RESOLVER env-var bypass for hermetic test\n[…]\n (bodyclose/contextcheck/errcheck/gosec/gocritic/...)\n- Add Makefile (build, test, test-race, lint, fuzz, vulncheck, install)\n- Add .github/workflows/{ci,release}.yml, .goreleaser.yaml, dependabot.yml",
          "is_bot": false,
          "headline": "bedrock: public-repo release blockers + CI tooling + test bypass (PR1…",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T20:47:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3cf14a3285c6c258a15424bf10057b58afe669b4",
          "body": null,
          "is_bot": false,
          "headline": "bedrock: network+concurrency hardening (PR2+3+7p+8+11)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T20:36:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "85a4e13b8ee5cc98786510069a51c0d93bce1f6c",
          "body": null,
          "is_bot": false,
          "headline": "bedrock: VMC EKU gate + parser hygiene (PR4+6)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T20:34:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2ff4d37649a9370edbed6394da4b1a2263a097ed",
          "body": null,
          "is_bot": false,
          "headline": "bedrock: output sanitisation + DANE hardening (PR5+9)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T20:31:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e6ee36986bd2ba3993be699aaef16f306686311",
          "body": null,
          "is_bot": false,
          "headline": "bedrock: discover HTTPS + ctx wrap (PR10+7ε)",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T20:30:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "98a58522dd3870f399a8937af4b5e46d3a87cc04",
          "body": "N/A is reserved for the operator's deliberate opt-out — the --no-active\ngate. When a check actually executed but had nothing to evaluate (the\noptional feature wasn't enabled, an upstream produced no parsed record,\nor the cached TLS state from a sibling check is missing), Info is the\nhonest status: t\n[…]\n test ./..., gofmt -l .\nall clean. Active scan against whitworth.org now shows the eight\nlisted sites as Info; --no-active mode still shows them as N/A\nbecause the deliberate-opt-out gate fires first.",
          "is_bot": false,
          "headline": "report Info instead of N/A when a check ran but had no input",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-17T02:02:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "adca4e143a205dc0c5339a74b9d84c89e93b29c6",
          "body": "Module path, all import paths, package doc strings, user-facing copy\n(help text, version line, report header, User-Agent), README, man page,\ngolden-file fixture, and the .gitignore binary entry all renamed.\nThe man page file moved from man/granite-scan.1 to man/bedrock.1.\n\nThe working-directory name\n[…]\n.., gofmt -l .\nall clean. `go run . --version` reports \"bedrock 0.1.0-dev darwin/arm64\".\nSmoke run against whitworth.org with --no-active still produces 57\nresults across the same 56 unique check IDs.",
          "is_bot": false,
          "headline": "rename project from granite-scan to bedrock",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-16T21:30:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9e3cc457cb278bcb54d7d9d868539d49d3952dee",
          "body": "Adds 13 new checks across the existing four categories plus a passive\nsubdomain enumerator:\n\n  Email/DNSSEC/Web checks\n    email.arc.*           — ARC (RFC 8617) prerequisites: DKIM keys,\n                            DMARC enforcement, deployment guidance\n    email.dkim.*          — selector probing \n[…]\n .\nall clean. Smoke run against whitworth.org with --no-active produces\n57 results across 56 unique check IDs, exit code reflects FAILs as\nbefore. quic-go and golang.org/x/crypto/ocsp added to go.mod.",
          "is_bot": false,
          "headline": "expand check coverage, add CI/regression tooling, broaden CLI/UX",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-16T21:25:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3ba5841e9637838967bade3a0706179bd0572777",
          "body": "53 checks live across all five categories. Highlights:\n\nDNS — SOA/MNAME hygiene (RFC 1912/2308), NS count + IPv4 /24\ndiversity + IPv6, CNAME apex prohibition + chain length, dangling-DNS\ndetection (S3, Heroku, GitHub Pages, Azure App Service markers + any\nNXDOMAIN target), AAAA, AXFR refusal probe p\n[…]\nAll tests +\ngo vet + gofmt clean. Smoke run against whitworth.org produces 53\nverdicts and correctly catches the apex→id.whitworth.org redirect\nhost-change, missing BIMI VMC, and SOA MINIMUM under 1h.",
          "is_bot": false,
          "headline": "implement DNS, DNSSEC, Email, WWW, and BIMI checks across the registry",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-16T20:00:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7053efca2c32b7a0b11edea3679626b32555306d",
          "body": "…ee renderers, category stubs\n\nFoundation for granite-scan. Establishes the probe.DNS/probe.HTTP API\nthat every check consumes, the report.Result type, the registry\ncontract, and stub checks per category so the binary runs end-to-end.\nMozilla server-side TLS v5.0 JSON embedded for WWW scoring.",
          "is_bot": false,
          "headline": "bootstrap: probe layer (DNS via miekg/dns + HTTP), Env, registry, thr…",
          "author_name": "Ryan Whitworth",
          "author_login": "rjwhitworth",
          "committed_at": "2026-04-16T19:45:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 6,
      "commits_last_year": 61,
      "latest_release_at": "2026-07-17T05:49:17Z",
      "latest_release_tag": "v1.2.1",
      "releases_from_tags": false,
      "days_since_last_push": 4,
      "active_weeks_last_year": 8,
      "days_since_latest_release": 4,
      "mean_days_between_releases": 18.1
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 62,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "github.com/whitworth-org/bedrock",
          "exists": true,
          "license": null,
          "keywords": [],
          "ecosystem": "go",
          "matches_repo": true,
          "registry_url": "https://pkg.go.dev/github.com/whitworth-org/bedrock",
          "is_deprecated": false,
          "latest_version": "v1.2.1",
          "repository_url": "https://github.com/whitworth-org/bedrock",
          "versions_count": 7,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": null,
          "latest_published_at": "2026-07-17T05:42:07Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 4
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0
      },
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "go.mod"
      ],
      "largest_source_bytes": 47924,
      "source_files_sampled": 139,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "go.mod"
      ],
      "advisories": {
        "error": null,
        "scope": "repository_graph",
        "source": "osv",
        "findings": [
          {
            "name": "golang.org/x/crypto",
            "direct": true,
            "version": "v0.54.0",
            "severity": "unknown",
            "ecosystem": "go",
            "cvss_score": null,
            "advisory_ids": [
              "GO-2026-5932"
            ],
            "fixed_version": null,
            "advisory_count": 1,
            "oldest_advisory_days": 14
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "unknown": 1
        },
        "advisory_count": 1,
        "affected_count": 1,
        "assessed_count": 10,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 1
      },
      "ecosystems": [
        "go"
      ],
      "dependencies": [
        {
          "name": "github.com/miekg/dns",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.1.72"
        },
        {
          "name": "github.com/quic-go/quic-go",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.60.0"
        },
        {
          "name": "golang.org/x/crypto",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.54.0"
        },
        {
          "name": "golang.org/x/net",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.57.0"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "github.com/miekg/dns",
            "direct": true,
            "version": "v1.1.72",
            "ecosystem": "go"
          },
          {
            "name": "github.com/quic-go/quic-go",
            "direct": true,
            "version": "v0.60.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/crypto",
            "direct": true,
            "version": "v0.54.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/net",
            "direct": true,
            "version": "v0.57.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/quic-go/qpack",
            "direct": false,
            "version": "v0.6.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/mod",
            "direct": false,
            "version": "v0.37.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/sync",
            "direct": false,
            "version": "v0.22.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/sys",
            "direct": false,
            "version": "v0.47.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/text",
            "direct": false,
            "version": "v0.40.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/tools",
            "direct": false,
            "version": "v0.47.0",
            "ecosystem": "go"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 10,
        "direct_count": 4,
        "indirect_count": 6
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 28,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 1,
        "closed_unmerged_prs": 24
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "rjwhitworth",
          "commits": 61,
          "avatar_url": "https://avatars.githubusercontent.com/u/3759824?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "kite-install-baseline.yml",
        "kite-on-demand.yml",
        "kite-preemption-retry.yml",
        "kite-skip-notice.yml",
        "raptor-agentic-review.lock.yml",
        "raptor-baseline-scan.lock.yml",
        "raptor-comment-reply.lock.yml",
        "release.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [
        ".golangci.yml"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "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": "21 out of 21 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/21 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": 10,
            "reason": "project is fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 8,
            "reason": "dependency not pinned by hash detected -- score normalized to 8",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 9,
            "reason": "SAST tool is not run on all commits -- score normalized to 9",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file 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": 9,
            "reason": "1 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "6cd543d0d9cba8109e46a1b6e0683377167d7564",
        "ran_at": "2026-07-22T05:23:42Z",
        "aggregate_score": 6.7,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-20T08:59:37Z",
      "oldest_open_prs": [
        {
          "number": 54,
          "created_at": "2026-07-17T19:04:12Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 55,
          "created_at": "2026-07-17T19:04:19Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-17T05:42:08Z",
      "ci_last_conclusion": "SKIPPED",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/whitworth-org/bedrock",
    "host": "github.com",
    "name": "bedrock",
    "owner": "whitworth-org"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 59,
      "inputs": {
        "security": 71,
        "vitality": 77,
        "community": 24,
        "governance": 52,
        "engineering": 70
      },
      "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": 61,
              "human_commit_share": 1,
              "days_since_last_push": 4,
              "active_weeks_last_year": 8
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "8/52 weeks with commits",
                "points": 5.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "61 commits in the last year",
                "points": 16.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 61
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 6,
              "latest_release_tag": "v1.2.1",
              "releases_from_tags": false,
              "days_since_latest_release": 4,
              "mean_days_between_releases": 18.1
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "6 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 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 ~18.1 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 18.1
                    }
                  }
                ],
                "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": "critical",
        "name": "Community & Adoption",
        "value": 24,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 52,
        "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": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 67,
            "inputs": {
              "merged_prs": 28,
              "open_issues": 0,
              "closed_issues": 1,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 24
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "100% of issues closed",
                "points": 46.8,
                "status": "met",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "28/52 decided PRs merged",
                "points": 20.6,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 28,
                      "decided": 52
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/21 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 46,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "whitworth-org",
              "public_repos": 3,
              "account_age_days": 2289
            },
            "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": "0 followers of whitworth-org",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "whitworth-org"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "3 public repos, account ~6 yr old",
                "points": 16.4,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 3
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 6
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "github.com/whitworth-org/bedrock"
              ],
              "ecosystems": "go",
              "any_deprecated": false,
              "min_days_since_publish": 4
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on go",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "go"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 4 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "7 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 70,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "9 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 9
                    }
                  }
                ],
                "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": ".golangci.yml",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".golangci.yml"
                    }
                  }
                ],
                "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": "21 out of 21 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "good",
        "name": "Security",
        "value": 71,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 67,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 6.7
            },
            "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": "21 out of 21 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/21 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 fuzzed",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 8",
                "points": 4,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 9",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "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": "1 existing vulnerabilities detected",
                "points": 6.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories. Remaining weights renormalized. Matched 10 resolved dependencies against OSV. This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "indirect_dependencies_free_of_known_advisories"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_repository",
                "params": {
                  "assessed": 10
                }
              },
              {
                "code": "advisories_repo_graph_caveat",
                "params": {}
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 89,
            "inputs": {
              "source": "osv",
              "advisories": 1,
              "affected_packages": 1,
              "assessed_packages": 10,
              "unassessed_packages": 0,
              "affected_by_severity": "unknown 1",
              "direct_affected_packages": 1
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "1 affected: golang.org/x/crypto v0.54.0 (unknown)",
                "points": 26.6,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "golang.org/x/crypto v0.54.0 (unknown)"
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "transitive set not separable from development and test dependencies in this scope",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_scope_not_separable",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory has been public longer than 90 days",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "advisories_none_stale",
                    "params": {
                      "days": 90
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 10,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "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": 2
            },
            "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": 72,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.984,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "60 of 61 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 60,
                      "sampled": 61
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "excellent",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [
                "Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "go.mod"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Makefile"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": ".golangci.yml",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".golangci.yml"
                    }
                  }
                ],
                "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 61",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 61
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "dependency automation configured, none observed in the sampled commits",
                "points": 5,
                "status": "partial",
                "details": [
                  {
                    "code": "dependency_bot_config_only",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 8",
                "points": 8,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 47924,
              "source_files_sampled": 139,
              "oversized_source_files": 0
            },
            "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": "0/139 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 139,
                      "oversized": 0
                    }
                  }
                ],
                "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": [],
  "report_type": "repository",
  "generated_at": "2026-07-22T05:23:57.859269Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/w/whitworth-org/bedrock.svg",
  "full_name": "whitworth-org/bedrock",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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