Raw JSON report machine-readable
{
"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"
}