公开记录
软件健康报告模式 0.27.0 · 指标 1.13.0 · 2026-07-28 07:53 UTC

gballer77 / gspec

JavaScript · AstroMIT★ 6 星标⑂ 2 复刻始于 2026年2月在 GitHub 上查看 ↗

gballer77/gspec 的健康指数为 100 分中的 58 分,处于「中等」区间。 其得分最高的类别是Vitality(85/100),最低的是Community & Adoption(35/100)。 最近一次更新在今天。 近期的大部分工作由 1 位贡献者完成。

58
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

Gregory Ball个人账户
5 关注者11 个公开仓库始于 2021年5月Clarity Innovations

该仓库由个人账户拥有。相较于组织支持的项目,单一所有者项目的延续性风险更高。

软件包生态系统

注册表软件包版本月下载量版本数最近发布标签
npmgspec2.6.01,434352 天前
npmpages指向其他仓库——不计分0.0.161,850144669 天前angular2lemetry

按类别列示的指标

活力

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

85优秀 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 0 天前
11.1/36提交节奏 — 52 周中有 16 周有提交
18/18提交量 — 最近一年 142 次提交
10/10OpenSSF Scorecard:Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year142
human_commit_share1
days_since_last_push0
active_weeks_last_year16

发布纪律

100优秀
评分方式
27/27有发布版本 — 已发布 36 个发布版本
36/36发布时效 — 最近一次发布版本于 2 天前
27/27发布节奏 — 约每 0.4 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count36
latest_release_tagv2.6.0
releases_from_tags
days_since_latest_release2
mean_days_between_releases0.4
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

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

35存在风险 · 占总体的 18%
评分方式
11.3/60星标 — 6 个星标
0/25复刻 — 2 个复刻
0/15关注者 — 0 位关注者
所用输入
forks2
stars6
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
评分方式
42.1/80月度下载量 — npm 合计每月 1,434 次下载
0/20注册表被依赖数 — 该生态系统不报告此项
所用输入
packagesgspec
dependents
ecosystemsnpm
total_downloads
monthly_downloads1,434
已排除计分(无数据或不适用):注册表被依赖数。 其余权重已重新归一化。

可持续性与治理

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

55中等 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
3.1/22.5提交分布 — 头号贡献者编写了 86% 的提交
2.7/13.5贡献者广度 — 2 位贡献者
6/10OpenSSF Scorecard:Contributors — project has 2 contributing companies or organizations -- score normalized to 6
所用输入
bus_factor1
contributors_sampled2
top_contributor_share0.863
评分方式
0/46.8议题解决 — 没有议题或无数据
38.2/38.3PR 接受 — 已裁定的 PR 中 14/14 已合并
0/15OpenSSF Scorecard:Code-Review — Found 0/30 approved changesets -- score normalized to 0
所用输入
merged_prs14
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
已排除计分(无数据或不适用):议题解决。 其余权重已重新归一化。
评分方式
10/30所有权背书 — 个人(用户)账户
0/20已验证域名 — 不适用于个人账户
5.6/25所有者影响力 — gballer77 有 5 位关注者
18.2/25既往记录 — 11 个公开仓库,账户约 5 年
所用输入
followers5
owner_typeUser
is_verified
owner_logingballer77
public_repos11
account_age_days1,897
已排除计分(无数据或不适用):已验证域名。 其余权重已重新归一化。
评分方式
25/25已发布且可解析 — npm 上有 1 个软件包
35/35发布时效 — 最近一次发布于 2 天前
20/20版本历史 — 35 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagesgspec
ecosystemsnpm
any_deprecated
min_days_since_publish2

工程质量

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

58中等 · 占总体的 20%

工程实践

60中等
评分方式
24/24CI 工作流 — 1 个工作流
24/24存在测试
0/16Linter 配置
0/9.6Pre-commit 钩子
0/6.4.editorconfig
0/20OpenSSF Scorecard:CI-Tests — 无数据
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config
已排除计分(无数据或不适用):OpenSSF Scorecard:CI-Tests。 其余权重已重新归一化。

文档

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

安全

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

50中等 · 占总体的 16%

安全态势

37存在风险
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 无数据
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
1.5/2.5Contributors — project has 2 contributing companies or organizations -- score normalized to 6
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
1/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 2
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — 无数据
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 28 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate3.7
已排除计分(无数据或不适用):ci_tests, signed_releases。 其余权重已重新归一化。
评分方式
35/35直接依赖不含已知公告 — 没有直接依赖携带已知公告
25/25间接依赖不含已知公告 — 没有间接依赖携带已知公告
0/40没有长期未处理的公告 — 没有公告带有发布日期
所用输入
sourceosv
advisories0
affected_packages0
assessed_packages8
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
已排除计分(无数据或不适用):没有长期未处理的公告。 其余权重已重新归一化。 比对的是 npm:gspec@2.6.0 的运行时依赖闭包——安装已发布的软件包时真正被拉取进来的内容——共 8 个软件包。 未对可达性进行分析。

AI 就绪度

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

70良好 · 占总体的 0%
评分方式
45/45代理指令 — CLAUDE.md, website/CLAUDE.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 100 次人类提交中有 83 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.83
agent_instruction_filesCLAUDE.md, website/CLAUDE.md
agent_instruction_max_bytes5,570
评分方式
0/18一条命令的引导启动
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — website/tsconfig.json
10/10可复现环境 — lockfile
10/10已体现的代理实践 — 最近 100 次提交中有 55 次由代理编写或署名代理
0/8自动化维护 — 未观察到自动依赖更新
2/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 2
所用输入
has_nix
has_tests
lockfilespackage-lock.json
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configswebsite/tsconfig.json
agent_commit_share0.55
toolchain_manifests
dependency_bot_commit_share0
评分方式
27/45可类型检查的代码 — JavaScript,已配置类型检查(website/tsconfig.json)
52.5/55可控的文件大小 — 采样的 44 个源文件中有 2 个超过 60KB
所用输入
primary_languageJavaScript
largest_source_bytes81,308
source_files_sampled44
oversized_source_files2

关键数据

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

数据采集警告

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • npm package 'pages' points at a different repository (https://github.com/m2mIO/pages); excluded from ecosystem scoring
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

更多细节

Star 与 Fork 历史 0 ★ / 2 ⇿
0Star
2Fork

每颗 star 和每个 fork 的添加时间,来自 GitHub 并按天汇总。累计增长位于其构成来源——每日新增——的正上方,二者可相互对照:稳定的自然增长与短暂的突增形态截然不同。当这一差别可被衡量时,它会作为增长真实性予以报告。

111222212026-052026-062026-06
OpenSSF Scorecard 3.7 / 10
3.7综合

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
不适用CI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
6Contributorsproject has 2 contributing companies or organizations -- score normalized to 6
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
2Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 2
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
不适用Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities28 existing vulnerabilities detected
直接依赖 7
注册表软件包版本约束清单文件
npm@clack/prompts^1.7.0package.json
npmchalk^5.6.2package.json
npmcommander^11.1.0package.json
npm@tailwindcss/typography^0.5.19website/package.json
npm@tailwindcss/vite^4.2.1website/package.json
npmastro^6.0.4website/package.json
npmtailwindcss^4.2.1website/package.json
全部依赖 未采集

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

依赖安全公告 0

安装 npm:gspec@2.6.0 会引入 8 个包(直接与传递):其中 0 个存在已知公告,0 个为直接依赖。

没有已知公告影响已评估的依赖。

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

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 1313,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "CSS": 4084,
        "Astro": 305318,
        "JavaScript": 365392
      },
      "pushed_at": "2026-07-27T18:51:39Z",
      "created_at": "2026-02-10T23:44:54Z",
      "owner_type": "User",
      "updated_at": "2026-07-26T03:28:00Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "JavaScript",
      "significant_languages": [
        "JavaScript",
        "Astro"
      ]
    },
    "owner": {
      "blog": "baller.software",
      "name": "Gregory Ball",
      "type": "User",
      "login": "gballer77",
      "company": "Clarity Innovations",
      "location": "Texas",
      "followers": 5,
      "avatar_url": "https://avatars.githubusercontent.com/u/84363550?v=4",
      "created_at": "2021-05-18T02:43:08Z",
      "is_verified": null,
      "public_repos": 11,
      "account_age_days": 1897
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v2.6.0",
          "kind": "minor",
          "published_at": "2026-07-26T03:28:25Z"
        },
        {
          "tag": "v2.5.1",
          "kind": "patch",
          "published_at": "2026-07-26T01:59:54Z"
        },
        {
          "tag": "v2.5.0",
          "kind": "minor",
          "published_at": "2026-07-25T20:45:55Z"
        },
        {
          "tag": "v2.3.0",
          "kind": "minor",
          "published_at": "2026-07-24T23:22:21Z"
        },
        {
          "tag": "v2.2.2",
          "kind": "patch",
          "published_at": "2026-07-24T23:09:53Z"
        },
        {
          "tag": "v2.2.1",
          "kind": "patch",
          "published_at": "2026-07-24T22:37:24Z"
        },
        {
          "tag": "v2.1.1",
          "kind": "patch",
          "published_at": "2026-07-23T23:51:02Z"
        },
        {
          "tag": "v2.1.0",
          "kind": "minor",
          "published_at": "2026-07-23T15:15:09Z"
        },
        {
          "tag": "v2.0.1",
          "kind": "patch",
          "published_at": "2026-07-23T03:11:40Z"
        },
        {
          "tag": "v2.0.0",
          "kind": "major",
          "published_at": "2026-07-22T20:13:47Z"
        },
        {
          "tag": "v1.20.0",
          "kind": "minor",
          "published_at": "2026-07-20T22:18:42Z"
        },
        {
          "tag": "v1.18.3",
          "kind": "patch",
          "published_at": "2026-07-10T14:49:07Z"
        },
        {
          "tag": "v1.18.2",
          "kind": "patch",
          "published_at": "2026-05-20T19:59:04Z"
        },
        {
          "tag": "v1.18.1",
          "kind": "patch",
          "published_at": "2026-05-20T19:05:38Z"
        },
        {
          "tag": "v1.18.0",
          "kind": "minor",
          "published_at": "2026-05-12T00:44:25Z"
        },
        {
          "tag": "v1.17.1",
          "kind": "patch",
          "published_at": "2026-05-11T15:20:50Z"
        },
        {
          "tag": "v1.17.0",
          "kind": "minor",
          "published_at": "2026-05-08T01:58:48Z"
        },
        {
          "tag": "v1.16.0",
          "kind": "minor",
          "published_at": "2026-04-24T22:47:54Z"
        },
        {
          "tag": "v1.15.0",
          "kind": "minor",
          "published_at": "2026-04-22T03:17:08Z"
        },
        {
          "tag": "v1.14.0",
          "kind": "minor",
          "published_at": "2026-04-16T03:04:44Z"
        },
        {
          "tag": "v1.13.2",
          "kind": "patch",
          "published_at": "2026-04-15T22:32:44Z"
        },
        {
          "tag": "v1.13.1",
          "kind": "patch",
          "published_at": "2026-04-14T01:24:26Z"
        },
        {
          "tag": "v1.13.0",
          "kind": "minor",
          "published_at": "2026-04-13T23:20:34Z"
        },
        {
          "tag": "v1.11.0",
          "kind": "minor",
          "published_at": "2026-04-13T17:01:04Z"
        },
        {
          "tag": "v1.10.0",
          "kind": "minor",
          "published_at": "2026-04-13T14:38:37Z"
        },
        {
          "tag": "v1.7.0",
          "kind": "minor",
          "published_at": "2026-03-14T22:11:41Z"
        },
        {
          "tag": "v1.6.0",
          "kind": "minor",
          "published_at": "2026-03-13T02:34:57Z"
        },
        {
          "tag": "v1.5.1",
          "kind": "patch",
          "published_at": "2026-03-13T01:13:49Z"
        },
        {
          "tag": "v1.5.0",
          "kind": "minor",
          "published_at": "2026-03-13T01:09:25Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2026-03-05T00:53:35Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2026-02-24T22:11:29Z"
        },
        {
          "tag": "v1.1.2",
          "kind": "patch",
          "published_at": "2026-02-22T02:18:02Z"
        },
        {
          "tag": "v1.1.1",
          "kind": "patch",
          "published_at": "2026-02-21T18:37:38Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-02-20T21:58:53Z"
        },
        {
          "tag": "v1.0.3",
          "kind": "patch",
          "published_at": "2026-02-13T18:47:17Z"
        },
        {
          "tag": "v1.0.2",
          "kind": "patch",
          "published_at": "2026-02-13T18:42:13Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "04dfc9cd3ab7d627f5f5f2fc1347af07494160b5",
          "body": "Run each build stage on a right-sized model to control token cost. A `models`\nmap in .gspec/config.json (project) or ~/.gspec/config.json (global) assigns a\nmodel per agent, resolved most-specific-first — exact agent name > role tier\n(writer/qa/planner/implementer/researcher/inspector) > default — w\n[…]\nty notes), changelog, design doc, build.astro, docs.astro.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EGkH6a89pX6KDQZ2aCNNMf",
          "is_bot": false,
          "headline": "v2.6.0: per-agent model assignment via config",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-26T03:27:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e9030f6187b79e43be5455a3340faf566dc2c208",
          "body": "The features stage fans out one feature-writer per feature and validates only\nafter the whole fan-out completes, so a writer failing (e.g. token exhaustion)\npauses the run before any memoization — and the resume re-ran the planner and\nevery writer, regenerating already-written PRDs (re-spending thei\n[…]\nDocs: changelog entry, design doc §13 note; version 2.5.1.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EGkH6a89pX6KDQZ2aCNNMf",
          "is_bot": false,
          "headline": "v2.5.1: checkpoint the feature-writing fan-out on resume",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-26T01:59:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "427de9e35e7c4f2af465dec8a6b00434521f68e5",
          "body": "…idation\n\nAddresses a field report from a full autonomous build where the QA loop never\nreached implementation. Bundles the durable QA failure log (previously staged as\n2.4.0, never tagged) with the QA-loop convergence fixes.\n\n- Durable, cumulative .gspec/build/qa-failures.md: every failing verdict \n[…]\nld.astro; version 2.5.0 in package.json/package-lock.json.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EGkH6a89pX6KDQZ2aCNNMf",
          "is_bot": false,
          "headline": "v2.5.0: QA loop converges — durable log, severity gate, resume re-val…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-25T20:44:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "29d0b86ad5fa389d98846beea87d251d2e87d87a",
          "body": "Fixes from a first-time-visitor review of the docs site:\n- All documented invocations now use the real /gspec-* command names\n  (bare forms like /profile never existed on any platform)\n- Build page: clarify nine agent stages plus a human review gate\n- Gloss \"harness\" and \"deployable\" at first use; s\n[…]\nre the first command and\n  link Antigravity, Open Code, and Pi on first mention\n\nAlso records the docs-sync exception in CLAUDE.md: website-only\nchanges ship without a version bump or changelog entry.",
          "is_bot": false,
          "headline": "docs(website): fix command names and newcomer readability issues",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-25T05:19:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7ad024abc6f0a88e74d370ab26aaf3a703eac2dd",
          "body": "…erals floor\n\nThree behavior changes, each synced across plugin prose, runtime, docs, and site.\n\nPer-deployable architecture (two-tier): the Deployables table gates the layout.\nOne row keeps a single gspec/architecture.md; more than one splits C4-style into\na system tier (shared entities, inter-unit\n[…]\nosticism the identity-leak sweep sites.\n\nSite: 2.3.0 changelog entry; docs (architect/style/analyze/implement/build),\nbuild, and how-it-works pages synced; v2 design doc hook table and roster\nupdated.",
          "is_bot": false,
          "headline": "v2.3.0: per-deployable architecture, surgical QA revisions, token-lit…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-24T23:21:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f21d1dfcccd2302f1d35f6f1ad7d3dd3d1d7c320",
          "body": "MAX_FEATURES was 12, which doubled as the concurrency ceiling because the\nfeatures stage fanned out writers with Promise.all — so \"max features\" and\n\"max simultaneous headless agents\" were the same number. 12 was too low for\nthe most ambitious builds.\n\nDecouple the two: raise MAX_FEATURES to 24 and \n[…]\ntest.mjs: cap-at-24 truncation test (26-feature plan)\n- releases.astro: 2.2.2 changelog entry; version bump in package(-lock).json\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2.2.2: raise features cap to 24, bound writer fan-out concurrency",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-24T23:08:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c135f943045a5e5040970db3b365d54b78cdd114",
          "body": "The releases page had drifted two versions behind — 2.1.1 and 2.2.0 shipped\nwithout changelog entries, and 2.2.1 (feature decomposition) was missing too.\nAdd all three entries (newest-first, versions matching package.json).\n\nAdd a root CLAUDE.md that makes \"any user-facing code change updates the do\n[…]\n doc surfaces (changelog,\nREADME, design doc, plugin prose, website) and the tag-driven release flow, so\nthis drift doesn't recur.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: backfill changelog (2.1.1, 2.2.0, 2.2.1) and add docs-in-sync rule",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-24T22:53:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1b6c7c7a3ef60eca2bee8b1f4b97b41414513e9c",
          "body": "…build\n\nThe autonomous build's features stage called feature-writer once, and that\nagent emits exactly one PRD — so every `gspec build` produced a single feature,\nregardless of scope. The v2 design specified feature-writer ×N and the\ndecomposition judgment still lived in the interactive /gspec-featu\n[…]\ner xN\n- test/build-features.test.mjs (fan-out, single, fallback, dry-run)\n- seed feature-planner in the three existing build tests\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2.2.1: decompose the brief into multiple features in the autonomous …",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-24T22:34:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f761390c1f1c7d7c9f7ac417cfa15cfad5da7f8f",
          "body": "… prompts via @clack/prompts\n\n- New research stage in the build graph after the profile: research-planner\n  turns the profile + brief into a competitor plan, one competitor-researcher\n  fans out per competitor (capped at 6), research-writer synthesizes\n  gspec/research.md with auto-accepted findings\n[…]\nfirm/\n  text on a TTY, readline numbered fallback off-TTY so piped usage keeps working.\n- Website and docs updated for both (BuildTerminal component, platforms,\n  getting-started, design doc, README).",
          "is_bot": false,
          "headline": "v2.2.0: opt-in competitive research stage (--research); arrow-key CLI…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-24T18:22:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "00221642fc4a139b833daa57d7e32b73121c8038",
          "body": "The Pi emitter was written against tintinweb/pi-subagents (filename\nis authoritative there, no name field), but the documented prerequisite\nis npm:pi-subagents (nicobailon), whose loader silently skips any agent\nfile missing name: or description: in frontmatter, so installed gspec\nagents never appea\n[…]\ncription:\n- Glob maps to Pi's find builtin; glob is not a Pi builtin, and under a\n  strict tools: allowlist the entry matched nothing\n- regression test pins the contract on every emitted dist/pi agent",
          "is_bot": false,
          "headline": "v2.1.1: emit pi agent frontmatter for npm:pi-subagents",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-23T23:49:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "696aadd8274eb4c38510c1ea7be6ebfdcd5d6829",
          "body": "…ble failure reports\n\nNew features in the autonomous build:\n- Spec-review human gate between plan and implement: the run pauses (exit 0)\n  once every spec is written and before any code is generated; --resume\n  approves, --no-review skips (at launch or at resume). Pre-gate manifests\n  survive the up\n[…]\ns the three\n  run endings (review pause, failure pause, complete).\n\nWebsite updated: v2.1.0 release notes, build page reliability card,\ngetting started, and docs command reference cover the new flags.",
          "is_bot": false,
          "headline": "v2.1.0: spec-review gate before implementation, --qa-retries, actiona…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-23T14:50:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c2af4b6ffd8049e228875841e83947d7a984e674",
          "body": "- test/install-targets.test.mjs: each of the six targets installs into a\n  temp project with an isolated HOME; asserts the target layout, the\n  recorded .gspec/config.json target, and the installed preamble\n  (including the gspec-* commands-are-not-binaries warning)\n- test/build-engine.test.mjs: eng\n[…]\nes\n  must be emitted to dist/ for each engine target, and each engine\n  adapter's agentFile() must match where the installer puts agents\n- npm test now builds dist first (pretest) and CI runs npm test",
          "is_bot": false,
          "headline": "Add per-target regression tests for install and build engine resolution",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-23T03:15:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "23011ff8f013074cddebaa42c508b472a775b34e",
          "body": "…flow on every harness\n\nRunning gspec build in a project installed for Codex or Pi silently\nassumed Claude, failed with a missing-agent error, and pinned the wrong\nengine into the run manifest. And after intake, nothing told the user\nor the agent that exiting the session hands control to the runtime\n[…]\ncontinue prompts resume an in-flight build\n  (gspec build --resume) instead of routing to gspec-implement\n\nWebsite: 2.0.1 release notes; build and getting-started pages describe\nthe new engine default",
          "is_bot": false,
          "headline": "v2.0.1: default the build engine to the installed target; in-session …",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-23T03:09:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "05d85e8948087438031a21d6fdb8251d2dc96ebc",
          "body": "Add an Autonomous build section introducing /gspec-build and the headless\ngspec build CLI, frame the two ways to work (autonomous vs spec-by-spec),\nretitle the manual flow accordingly, and fix the platform-agnostic line to\ninclude Open Code and Pi.",
          "is_bot": false,
          "headline": "Lead the README with the 2.0 autonomous build; list all six platforms",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-22T20:10:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15f9182cda763522bd3ed8859785b9ec632d9bec",
          "body": "…sion check\n\ninstaller (bin/gspec.js):\n- cleanupStaleV1Skills: remove leftover v1 command-skill dirs that v2 no longer\n  emits, so stale copies can't shadow the new commands (install only overwrites,\n  never deletes). Scoped to LEGACY_V1_SKILL_NAMES so user skills are untouched.\n- checkGspecFiles: d\n[…]\n-harness detail from wordy prose bullets to one row per\n  capability with a state glyph plus a tight reason, leading deficiencies with\n  an explicit \"Gap:\" so they're scannable and tied to the matrix.",
          "is_bot": false,
          "headline": "Harden v1->v2 upgrade: skill cleanup, migrate prompt, extension colli…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-22T19:39:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "348f713055db38060e46477b4c78b24043400ef9",
          "body": "Expand the marketing site to reflect v2: add Build, How It Works, and\nPlatform Capabilities pages; introduce the AutonomousBuild home-page\nsection; and update platform lists to include Open Code and Pi. Refresh\ngspec specs (architecture, getting-started, home-page, practices,\nprofile) to match the nine-page site and two-path onboarding.",
          "is_bot": false,
          "headline": "Update website for gspec 2.0: autonomous build, new platforms and pages",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-22T18:24:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "16d2f3f47a54b89feeb257c152542c1e8b70b510",
          "body": "…ared floors\n\nExtract each file-write floor's decision logic into engine-neutral pure modules\nunder plugin/hooks/floors/ (spec-integrity, agnosticism, task-immutability,\npractices, and a full-tree scan aggregator). The Claude hooks become thin\nadapters over those modules; behavior is unchanged, veri\n[…]\n and the refactored Claude hooks still fire.\n\nTwo Codex-runtime assumptions need confirming on a real install: project-local\n.codex/hooks.json support, and the feature-flag key (codex_hooks vs hooks).",
          "is_bot": false,
          "headline": "Close the enforcement-floor gap on Codex (Stop-hook gate); extract sh…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-22T14:44:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6a0723790341cccb04f622b0308566f44cb35c23",
          "body": "- Move all current hooks into plugin/hooks/claude/. The claude/ folder marks them\n  Claude-specific and is stripped on install (source plugin/hooks/claude/x.mjs ->\n  installed .claude/hooks/x.mjs). Update the installer source path and the test\n  glob (plugin/hooks/*/*.test.mjs).\n- Add docs/harness-p\n[…]\ner-harness plan to close the enforcement-floor and\n  learning-loop gaps (cheap way vs right way), grounded in each platform's verified\n  hook/memory capabilities. Pointer added from the v2 design doc.",
          "is_bot": false,
          "headline": "Relocate Claude hooks into plugin/hooks/claude/; add harness-parity doc",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-22T14:35:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f9a7c8de74e75b64ec9819ca6469532680ddd737",
          "body": "…uation loop\n\n- Task immutability: new PreToolUse hook (gspec-task-immutability.mjs) freezes\n  checked-off plan tasks so a replan cannot edit, delete, or uncheck them;\n  replanning appends new tasks carrying a supersedes: marker. Teaches the rule\n  across the engineer persona, plan-decomposer, plan-\n[…]\nuation loop: while the unchecked-task\n  count keeps dropping, a fresh implementer resumes the reduced scope, capped by\n  MAX_SCOPE_RUNS and stopped by MAX_STALLS so a stuck scope falls to the QA gate.",
          "is_bot": false,
          "headline": "Add task-immutability guard, build learnings report, implement contin…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-22T01:03:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "42f4f1395abdb340afb89e5928c168dc160fac58",
          "body": "The pipeline command and runtime are renamed to \"build\" throughout:\n\n- CLI command `gspec pipeline` becomes `gspec build`\n- lib/pipeline.js becomes lib/build.js (runPipeline -> runBuild,\n  PIPELINE_DIR -> BUILD_DIR)\n- run-manifest state dir moves from .gspec/pipeline/ to .gspec/build/\n- command mark\n[…]\nn skills\n\nGeneric CI/CD \"pipeline\" references (practices/architecture personas)\nare intentionally left unchanged.\n\nAlso includes in-progress v2 agent-refactor work already present in the\nworking tree.",
          "is_bot": false,
          "headline": "Rename the autonomous \"idea to built\" pipeline to \"build\"",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T22:47:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "56a6b47326d90e3b24fb9a5d0ed530cf4c476950",
          "body": "Pi joins claude/opencode/codex/cursor as a native v2 target. The build\nemits sub-agents to .pi/agents/, prompt templates to .pi/prompts/, and\nthe persona/convention skill catalog to .pi/skills/. Like the other\nnon-Claude targets, Pi cannot preload a named skill subset (its skills:\nfrontmatter select\n[…]\n validators read-only.\n\nPi sub-agents come from the pi-subagents extension, so the installer\nprints that as a hard prerequisite after a Pi install, and the README\nand getting-started page call it out.",
          "is_bot": false,
          "headline": "Make v2 work with Pi via the pi-subagents extension",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:49:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9b79735348efa41dda34b7cd8e96909ea24a898f",
          "body": "…trail",
          "is_bot": false,
          "headline": "v2: show version in the install banner and ignore the decision-audit …",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c56fc8e82fdb927241a504e79a81ca9ab99676ec",
          "body": "The gspec-practices persona and practices-writer now mandate a\nmachine-readable Enforcement block so practices run as hooks rather\nthan living only as advisory context.",
          "is_bot": false,
          "headline": "v2: require an Enforcement block in the practices guide",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b5908be6a903dc02b940d1813e94cb89fbca25c",
          "body": null,
          "is_bot": false,
          "headline": "v2: relocate v1 command sources under commands/v1/",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c3812586a46e32e580f9f7a9157058c5387d691c",
          "body": "The website's own specs still referenced the old pages/ folder after the\ndirectory was renamed. Update architecture.md (deploy trigger/build/artifact\npaths, now matching publish.yml), practices.md (folder reference and the\nlighthouse enforcement rule's applies_to glob, which otherwise matched\nnothing), and stack.md (package.json location, structure block, style.md\npaths). Astro's src/pages/ routing references are unchanged.",
          "is_bot": false,
          "headline": "Reconcile website specs with the pages/ to website/ rename",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "337e8081760e33857972301a1d25420f309723ad",
          "body": "manifest.js is build-time-only data (the skill/agent/command catalog) imported\nsolely by scripts/build.js and never shipped in the package. Colocating it with\nits only consumer keeps the repo root to shipped/tool concerns. Source paths\nresolve via SOURCE_ROOT, independent of the manifest's own location.",
          "is_bot": false,
          "headline": "Move manifest.js into scripts/",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "464259a047be29ca3e154803fdcf536688998f18",
          "body": "bin/ should hold only the executable CLI entry (gspec.js, the sole package bin).\nemitters.js and pipeline.js are library modules imported by the CLI and, for\nemitters, by scripts/build.js. Relocating them to lib/ keeps bin/ to real\nentry points and removes build.js's reach into bin/. Adds lib/ to files so the\nmodules still ship in the published package.",
          "is_bot": false,
          "headline": "Move emitters.js and pipeline.js from bin/ into lib/",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "273f0686a2dbe0a443b4de59181328ddaa0105a2",
          "body": "The Astro marketing/docs site was pages/; website/ names it for what it is.\nIts living specs (profile, stack, architecture, style, practices, features)\nwere authored at the repo root gspec/ even though they describe the site, so\nthey move under website/gspec/ next to the code they spec. website/CLAU\n[…]\nPages deploy workflow to build from website/, and deletes the\nstale root CLAUDE.md (a duplicate gspec preamble pointing at the now-moved\nroot gspec/; the repo root is the tool, not a specced project).",
          "is_bot": false,
          "headline": "Rename pages/ to website/ and move the specs into website/gspec/",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d159b4910e21ee339a58db91de87f9ec2ae63cc4",
          "body": "…late to preamble\n\nGroup the Claude Code primitives (agents, commands, hooks, skills) under a\nsingle plugin/ directory matching the plugin convention, leaving bin/ and\nscripts/ for tool code. Build resolves manifest sources from plugin/ via a new\nSOURCE_ROOT; the installer reads hooks from plugin/ho\n[…]\nts marker to <!-- gspec:preamble -->, with a\nback-compat shim that still matches the legacy <!-- gspec:spec-sync --> marker\nso re-installs migrate an existing block in place instead of duplicating it.",
          "is_bot": false,
          "headline": "Move agents/commands/hooks/skills into plugin/; rename spec-sync temp…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "edbda01cfe09c0ef0126c10decb85ebaa82b1caa",
          "body": "Model-free lifecycle guards. practices-enforce (PostToolUse) lints each\nwritten file against the deterministic checks declared in practices.md's\nEnforcement block. The reconcile pair (PostToolUse marker + Stop nudge)\nblocks a turn once when a session changed source but touched nothing under\ngspec/, so specs stay in sync. Both fail open. Wired into the installer via\nHOOK_SPECS/HOOK_SUPPORT_FILES and recorded as built in the v2 design doc.",
          "is_bot": false,
          "headline": "Add practices-enforcement and spec-reconcile hooks",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c725dcb2ec9dea16f9267bb76c2a97800d610b6f",
          "body": "… complete\n\nFinal step of the learning loop. Capture no longer depends solely on a\ncorrected agent self-recording.\n\n- new SubagentStop hook gspec-subagent-capture (matcher *): on a FAILing QA\n  verdict, appends timestamp · agent_type · verdict excerpt to\n  .gspec/agent-runs/feedback-log.md. Model-fr\n[…]\n-tagged memory →\ndistiller proposal (T2) → human-approved skill edit → better agents next run;\norchestrator judgment (T3) rides the same rails.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2: T4 — subagent-capture hook (auto feedback capture); learning loop…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "58d7d6e67fc7d2739bb935a54566ee270f2d8627",
          "body": "…pe/fan-out judgment)\n\nThird step of the learning loop: move the scope/granularity/fan-out decision out\nof hard-coded JS into a trainable skill.\n\n- new gspec-orchestrator skill: right-sized scopes, dependency ordering,\n  file-disjoint fan-out, and the wave build-plan JSON contract\n- new build-orches\n[…]\n. Impl-validator gate unchanged.\n- /gspec-implement applies the same judgment; non-Claude targets inline it via a\n  new alsoSkills degrade hook\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2: T3 — gspec-orchestrator skill + build-orchestrator (trainable sco…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "77b4f06ddc9ed87397eee72ca41643b95d82efc3",
          "body": "…ory→skill promotion)\n\nSecond step of the learning loop: promote address-tagged agent lessons into\nskills through a reviewed path — never a silent auto-edit.\n\n- new distiller agent (steward+qa, read-only): reads agents' memory, judges\n  which lessons are general/recurring/uncovered, proposes surgica\n[…]\nt auto-enabled, so\n  tool limits alone can't stop a skill rewrite). Durable promotion goes to gspec\n  SOURCE skills (unguarded) and reinstalls.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2: T2 — distiller + /gspec-distill + skill-write guard (reviewed mem…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3154fea3aa2e7a30e9ac248f758ebc12417bb070",
          "body": "…ok + init scope)\n\nFirst step of the learning loop. Claude-only (other targets have no silo).\n\n- new gspec-memory convention skill: feedback-driven capture, target+layer\n  address tag, lean MEMORY.md curation, producer≠checker note\n- new PreToolUse hook gspec-memory-address-tag: blocks an untagged w\n[…]\ninto non-Claude inline/degrade\n- installer prompts for memory scope (project|local) at init and stamps each\n  agent's memory: field; default-on\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2: T1 — activate per-agent memory (feedback capture + address-tag ho…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8c2c479adcf9e3245ff5d2156f014b14ca4e80e4",
          "body": "…lidator\n\nExpands §13's learning-loop bullet into a concrete, sequenced plan (T1 activate\nper-agent memory → T2 distiller → T3 gspec-orchestrator skill → T4 loop hooks),\nrecorded not yet built. Mirrors how implementation-validator was recorded first.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2: record learning-loop (\"training\") plan — next build after impl-va…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9d3e50da79803b6b134a512d736e0849f8386bef",
          "body": "… gate\n\nCloses the last producer≠checker gap: /gspec-implement's output (code) now\nhas a real gate instead of trusting the implementer's own tests.\n\n- new agent implementation-validator (gspec-qa+engineer+practices; Bash, read-only)\n- architecture.md gains a Deployables table (name·dir·build·test); \n[…]\n-implement gains the post-phase gate; gspec-audit gains a `deployable`\n  drift category; registered in manifest (+ degrade self-review fold-in)\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v2: implementation-validator — deterministic verify.sh + DoD judgment…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c7053595f061fafc860793f55cd24cd674efc75e",
          "body": "Plan only — not built (design doc §13). Producer command flows should, after\nthe writer returns, present the deferred decisions / assumptions it recorded\none at a time and offer to resolve (revise) or accept — closing the loop for\nquestions the front-loaded interview couldn't anticipate (the agent d\n[…]\nt. Prompt-level change to command bodies; no new plumbing.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2: record 'review deferred decisions after production' plan",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1226878da0d5521bdb3df60c14626c22c1def792",
          "body": "Plan only — not built. Records the implementation verification gate in the\ndesign doc (§7 note + §13):\n- implementation-validator = producer!=checker for code (supersedes the vague\n  'code-reviewer'). Two-part gate, honors --no-qa.\n- Deterministic: BUILD + TEST only (not the full practices pipeline \n[…]\n gains the deployables table; gspec-audit catches\n  drift.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2: record implementation-validator plan (deterministic build+test gate)",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "be262dea740a3312b1400367e08d246624e913eb",
          "body": "templates/spec-sync.md is installed into each harness's native rules mechanism\n(CLAUDE.md, .cursor/rules/gspec.mdc, .agents/rules/gspec.md, AGENTS.md). Updated\nfor v2:\n- 'gspec skill' -> 'gspec-* command'; note the built-in producer!=checker\n  quality-review gate (skip with --no-qa).\n- Added gspec-p\n[…]\niles. Verified it installs into\nClaude/Cursor/Antigravity.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2: refresh spec-sync rules block (practices as active coding rules)",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "188984453f2effb9794b618c47edb5f51ecec07e",
          "body": "Antigravity emission, verified vs docs (antigravity.google, 2026-07-12; current\ndefault is PLURAL .agents/, singular .agent/ is the legacy fallback):\n- No agent FILES (sub-agents are runtime-only via the Agent Manager), so\n  personas/conventions become SKILLS (.agents/skills/<n>/SKILL.md) and each\n \n[…]\nkills + workflows (correct for a no-agent-files platform).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2 multi-target: Antigravity (skills + workflows) — all 5 targets done",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fc90240fc999a645a8e924ad30200046ee4dfa2f",
          "body": "Cursor 2.4+ native emission, verified vs docs (cursor.com/docs, 2026-07-12):\n- Agents = .cursor/agents/<name>.md (markdown; the body IS the prompt).\n  Frontmatter is exactly name/description/model/readonly — NO 'tools' field, so\n  permission is the readonly boolean (derived from write-capability); m\n[…]\nnts/skills/) + workflows-as-commands (.agents/workflows/).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2 multi-target: Cursor native (markdown agents)",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5a0226f90f29c545bc6f29c7eb782fc7801c8af6",
          "body": "Codex native emission, verified against Codex docs (learn.chatgpt.com, 2026-07-12):\n- Agents = standalone TOML at .codex/agents/<name>.toml. The system prompt is the\n  INLINE triple-quoted developer_instructions; permission is sandbox_mode\n  (read-only vs workspace-write, derived from write-capabili\n[…]\nn\nagents) + Antigravity (stays composed — no agent files).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2 multi-target: Codex native (TOML agents)",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4f6f38baa881a7da7413040e1275c23987f3b4a6",
          "body": "Validated (source-verified) that OpenCode, Codex, and Cursor all now have native\nfile-based sub-agents + skills + commands — they converged on Claude Code's model\nin late 2025/early 2026. Only Antigravity lacks agent files. So a single-file\n'degrade' is only correct for non-agent targets.\n\n- OpenCod\n[…]\n and Cursor (markdown agents); Antigravity stays composed.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2 multi-target: OpenCode native + composed degrade for the rest",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c6c305e1ce24eff05f70353a8116ecbb516d864f",
          "body": "The buildable-now slice of Layer 5 — two PostToolUse hooks (Claude Code only),\nmodel-free and fail-open (any internal error -> exit 0, never breaks a session):\n- gspec-agnosticism-guard: after a Write/Edit to a NON-profile spec, derives the\n  product name from gspec/profile.md and flags any leak (ex\n[…]\np. Verified: simulated events + install/merge/idempotency.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2 Layer 5: near-term hooks (agnosticism guard + spec-integrity)",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2a71cf435f8b5ec1ade3022e270c79fcb039d8b5",
          "body": "The runtime layer (design §8) — turns gspec from prompt files into an\nexecution framework. bin/pipeline.js drives idea -> built by running each stage\nas an ISOLATED headless run (`claude -p --agent <name>`); the filesystem (the\ngspec/ docs) is the shared state, so nothing accumulates in a context wi\n[…]\n needs a\nreal target project, so it is not exercised here.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2 runtime: gspec pipeline orchestration driver",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4bb2486e51fcfd4f2b527d8a6ef054ccd34a5961",
          "body": "Completes the command/agent surface migration (Claude legacy count now 0; the\nother four targets still build all 12 legacy skills, backward-compat intact):\n- audit: gspec-steward + codebase-inspector (reads code, has Bash); reconciles\n  drift one at a time; reuses feature-writer to draft orphan PRDs\n[…]\nroven: producers, validators, investigators, transformers.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2: migrate audit, migrate, research — all 12 commands now on v2",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bc9d0cfd0c97b720c623a6f1e36e4461bc871709",
          "body": "Introduces the gspec-engineer persona and the transformer agent category\n(the last unproven agent shape):\n- plan-decomposer: read-only, returns a draft plan for the command's plan-mode\n  approval gate (the command writes the file after approval)\n- plan-validator: checks coverage, acyclic deps, safe \n[…]\n-cap validation caught an over-long trigger and was fixed.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2: migrate plan + implement (engineer + transformer category)",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dcbbaf4f3f52c75ff09c689cb21eabe3e6c06399",
          "body": "Four more capabilities on the v2 architecture (pure content + manifest; the\nbuild/emit/install plumbing is unchanged):\n- style (producer): gspec-designer + style-writer/style-validator; the .md/.html\n  format choice is resolved in content, not plumbing\n- practices (producer): gspec-practices + pract\n[…]\nch, implement, migrate); the other four targets unchanged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2: migrate style, practices, feature, architect slices",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c63c10204ce75d6848a3b09b2128ccff45a4d9f7",
          "body": "Introduce the v2 agent architecture plumbing (Claude-first; the other four\ntargets are unchanged and still build all 12 legacy skills):\n- manifest.js: per-class registry (V2_SKILLS/AGENTS/COMMANDS, V2_TARGETS,\n  MIGRATED_LEGACY)\n- emitters.js: buildAgentFrontmatter + Claude emitAgent/emitCommand\n- b\n[…]\nult,\n--no-qa). Design captured in docs/gspec-v2-design.md.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01GY2jBUVD6sCnkcvp6UGkTe",
          "is_bot": false,
          "headline": "v2: skill/agent/command artifact classes + first 3 vertical slices",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-21T16:41:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a9c477c1c8b25ef4f046bdd061d0d4e8d3746690",
          "body": "Adds Pi (pi.dev) as a supported install target alongside Claude Code,\nCursor, Antigravity, Codex, and Open Code. Release notes document the\nnew dual-emission target and the shared helper that now backs both Pi\nand Open Code.",
          "is_bot": false,
          "headline": "Bump version to 1.20.0 and add release notes",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-20T22:18:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4253e21c5e6b72b8bdb0cd4d8fa3ac89ce9e48a",
          "body": "Add Pi coding agent as an install target",
          "is_bot": false,
          "headline": "Merge pull request #16 from gballer77/pi-support",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-20T22:16:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "16f02cf65001aa075e938f873d2f55f425798c11",
          "body": "Pi (pi.dev) splits agent behavior across slash-command prompt\ntemplates and on-demand skills, mirroring Open Code's dual model but\nplacing commands in .pi/prompts/ rather than .pi/skills/. Factor the\ndual emit into a shared helper parameterized by command subdirectory\nso both targets share one code path, and surface Pi in the installer,\ndocs, and site platform lists.",
          "is_bot": false,
          "headline": "Add Pi coding agent as an install target",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-20T21:47:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e4ded1f39a2a8a99cccc3693369b930830afecc",
          "body": "Drop the NPM_TOKEN auth so npm publish authenticates through the OIDC\nexchange, and move the publish job to Node 24 for the npm 11.5.1+\nrequirement. Release creation is now idempotent so a retagged version\ncan re-run the workflow without failing on the existing release.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Publish to npm via trusted publishing (OIDC)",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-10T16:27:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1ba60540fd0e2551bc7cbd0ebfc351de8c9c39f4",
          "body": "The profile spec now covers product identity only; release notes and\nwebsite docs updated to match, including the Product Strategist role\nrename that shipped in the spec earlier.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.19.0 and add release notes",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-10T15:34:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1b3ef582ef800f6917a833f11505763c26b93eb4",
          "body": "Remove roadmap, business model, and metrics sections from profile spec",
          "is_bot": false,
          "headline": "Merge pull request #15 from gballer77/profile-spec-improvements",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-10T15:29:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a2fe4353a438bd4405f273e559079f257f567191",
          "body": "The profile defines what the product is, not how it gets there or how\nit's measured. Feature PRDs carry current state; go-to-market sections\nare now opt-in only when the user explicitly requests them.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Remove roadmap, business model, and metrics sections from profile spec",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-10T15:26:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b686629419301b39bcfcea20d8b2d3bd5f699bc3",
          "body": "Emit opencode prompts as commands plus skills",
          "is_bot": false,
          "headline": "Merge pull request #14 from gballer77/fix/opencode-slash-commands",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-10T14:58:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8741b30bb4d04b0d534defe648c9f58e44d7a2a2",
          "body": "Also syncs package-lock.json, which was stale at 1.10.0.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.18.3 and add release notes",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-10T14:48:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "efcf2ac05d8640f4415c4fe1c383a07be0164c71",
          "body": "opencode does not surface skills as slash commands; they sit behind the\n/skills picker and the agent's skill tool, so the documented /gspec-*\ninvocations never resolved. Ship each prompt twice for opencode:\n.opencode/commands/<name>.md backs user-invoked slash commands (with\n$ARGUMENTS substitution) and .opencode/skills/<name>/SKILL.md keeps\ndescription-triggered auto-loading by the agent.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Emit opencode prompts as commands plus skills",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-07-10T14:28:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "60498057cc3c692491761f7acab40f1865ce1de7",
          "body": "Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add robots.txt allowing AI crawlers from OpenAI, Anthropic, and Google",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-21T22:19:41Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4100e73bd0d138288d1cbf0471ba5fcc30eb4ee3",
          "body": "Trims every skill description to fit inside Claude Code's 250-char\nselection window. Previously 10 of the 12 descriptions ran 260-930\nchars, so the trigger guidance past char 250 was silently dropped when\nClaude decided whether to invoke a skill.\n\nTightens the build-time validator that landed in 1.1\n[…]\nt 1024), treating it as the build-blocking\nthreshold is the only way to keep descriptions inside the window\nClaude actually reads.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.18.2 and add release notes",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-20T19:58:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cf94bd69631e373056d5cca151856f06b2f8a5ad",
          "body": "Fixes a frontmatter bug where skill descriptions containing colons or\nembedded quotes (most visibly /gspec-implement) were emitted as\nunquoted YAML plain scalars and failed to parse in Claude Code,\nCursor, Antigravity, Codex, and OpenCode. The emitter now wraps every\nfrontmatter value in a properly \n[…]\ne decides\nwhether to invoke a skill). Trims /gspec-analyze, /gspec-audit, and\n/gspec-implement descriptions to clear the hard cap.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.18.1 and add release notes",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-20T19:03:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6d411789f2b277dfec4f85478deed583934ed380",
          "body": "Renames /gspec-tasks → /gspec-plan with sibling artifacts moving from\n*.tasks.md to *.plan.md, lets /gspec-implement skip its own plan-mode\napproval when every in-scope feature already has an approved plan\nfile, and extends /gspec-analyze with an optional feature-slug\nargument that scopes the run to one PRD and adds an Ambiguity &\nUnderspecification sweep against the document itself.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.18.0 and add release notes",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-12T00:43:42Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b63b9d1fac9e06b47ef915be8bdca54acc4ddec5",
          "body": "Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Render release summaries as HTML so <code> tags display correctly",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-11T15:34:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8c8e63ef3ffa3708320815f4afad50c27126e41e",
          "body": "Fixes ERR_MODULE_NOT_FOUND on `npx gspec` for 1.17.0. The shared\nemitter module was extracted to scripts/emitters.js but scripts/ is\nnot in the published `files` list, so bin/gspec.js shipped without\nits dependency. Moved to bin/emitters.js so it ships alongside the\nCLI entry point.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.17.1 and add release notes",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-11T15:18:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "56b7be5cf7810c70ab557915e1eb7ba8af673c88",
          "body": "The previous workflow auto-created releases by parsing commit messages\nfor \"for vX.Y.Z\". When the version-bump commit format changed to\n\"Bump version to X.Y.Z\", the regex stopped matching and v1.14 onward\nwere never published from CI. Tag pushes also did nothing because\nthere was no `tags:` trigger.\n[…]\nauto-generated notes, and publishes to npm. Push to main still builds\nand deploys the pages site but no longer attempts a release.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Switch release publishing to tag-driven CI flow",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-11T15:18:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6da60b4889cda054108217a5d97526a2213c9067",
          "body": "Each release article now has an id=\"v{version}\" anchor, and the\nversion badge is a clickable hash link so visitors can copy a direct\nURL to a specific release.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add per-version permalinks to the releases page",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-08T02:10:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4177ef9720f189def0f45eb6e714e0c892ab86a4",
          "body": "Adds /gspec-tasks for decomposing feature PRDs into ordered,\ndependency-aware task plans with parallel-execution markers, and a\nuser extension system that auto-installs skills from\n~/.gspec/extensions/ alongside the built-in commands.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.17.0 and add release notes",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-05-07T20:48:41Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "888234e62693dbf93a11583b8bb64b4cf6bc8ea5",
          "body": "Adds style.html format, gspec/design/ folder for external mockups,\n/gspec-audit command for spec-to-code drift detection, and broader\nproduct-type support in /gspec-profile.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.16.0 and add release notes",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-24T22:38:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c5766f4ecd57946e79be0568bece1dd42a05a83a",
          "body": "Adds skill routing triggers, the \"Prefer gspec skills\" spec-sync section,\nand overwrite-by-default behavior for `gspec save`.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 1.15.0 and add release notes",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-22T00:00:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2220da328757ec202feb872340f616809a5e867c",
          "body": "…s-OzbsL\n\nAdd \"spec before you build\" rule to spec-sync instructions",
          "is_bot": false,
          "headline": "Merge pull request #11 from gballer77/claude/update-gspec-instruction…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-16T02:59:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8120b295bdfd5ce1cea522697cf7c379ec7a8fa9",
          "body": "New minor version for the spec-first workflow and resolved specs\nchanges: \"spec before you build\" rule in spec-sync, and the\nno-open-questions policy across feature, architect, stack, and\nresearch commands.\n\nhttps://claude.ai/code/session_01HurNUUvtCbbUBGiMeqCu7v",
          "is_bot": false,
          "headline": "Bump version to 1.14.0 and add release notes",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-04-16T02:53:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "97731c628492780527f4f1a293807d79f6413caf",
          "body": "Apply the same \"resolve before saving\" policy to all remaining spec\ntemplates that allowed open questions:\n- gspec.stack.md: renamed \"Open Questions\" to \"Clarifications\", require\n  resolution before saving\n- gspec.research.md: updated PRD structure reference to match new policy\n- gspec.architect.md: changed missing-spec fallback from \"flag in Open\n  Decisions\" to \"ask the user to clarify\"\n\nhttps://claude.ai/code/session_01HurNUUvtCbbUBGiMeqCu7v",
          "is_bot": false,
          "headline": "Remove open questions from stack, research, and architect specs",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-04-16T02:39:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fff111f0bb3a636c5eaaa9160c8532ed43dfba6c",
          "body": "Feature PRDs and architecture documents should not contain unresolved\nopen questions. All questions must be asked to the user in conversation\nand resolved before the spec is saved. Only if the user explicitly\ndefers a question should it be recorded as a \"Deferred Decision.\"\n\nhttps://claude.ai/code/session_01HurNUUvtCbbUBGiMeqCu7v",
          "is_bot": false,
          "headline": "Require open questions to be resolved before saving specs",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-04-16T02:36:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "406f02d6e3acb2adaad9b3a9d5a6acdafe2d3c25",
          "body": "When a user asks for a feature not covered by an existing PRD, agents\nshould now run the gspec-feature command to create the spec before\nimplementing. This ensures every feature is specified before code is\nwritten.\n\nhttps://claude.ai/code/session_01HurNUUvtCbbUBGiMeqCu7v",
          "is_bot": false,
          "headline": "Add \"spec before you build\" rule to spec-sync instructions",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-04-16T02:23:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a54e1639470a67215509a5eb49b9c608a98210a",
          "body": "All specs except profile.md now explicitly prohibit including project names,\ncompany names, or business-specific context in generated output.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Enforce profile-agnostic output across all spec commands for v1.13.2",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-15T22:32:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1ae38db7c190f817ab76370af1bdeac511df7feb",
          "body": "Traditional SDD approaches (OpenAPI, BDD, DbC, MDD, ADRs, PRDs) are\ncondensed into a brief history section. The page now leads with agentic\nSDD — why AI agents need structured specs, how the workflow changes when\nagents are the implementers, and what makes agentic SDD different from\nits predecessors.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Refocus \"What is SDD?\" page on agentic SDD for the AI era",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-15T22:28:11Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "81f038f49d4de413c0c4fa00ad54e8064e7ff3c5",
          "body": "…IVcQ\n\nAdd \"What is SDD?\" educational page to the pages site",
          "is_bot": false,
          "headline": "Merge pull request #10 from gballer77/claude/add-sdd-education-page-4…",
          "author_name": "Gregory Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-15T21:37:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58d1c6cd8fa1a3746b1af2e3cca497b6990e00de",
          "body": "Adds an \"AI-Era SDD Tools\" section covering GitHub Spec Kit, OpenSpec,\nand Kiro with descriptions of their workflows and scope. Updates the\ngspec comparison section to include head-to-head comparisons with each\nof these frameworks alongside the classical SDD approaches.\n\nhttps://claude.ai/code/session_01Fsh7zh5ZaDseEfxQb99ypw",
          "is_bot": false,
          "headline": "Add Spec Kit, OpenSpec, and Kiro to the SDD education page",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-04-15T21:00:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26b26441f949c487494dbe80f5b715ceae0b1e4b",
          "body": "Adds a comprehensive article about Spec-Driven Development covering\ncore principles, common frameworks (OpenAPI, BDD, DbC, MDD, ADRs, PRDs),\nbenefits, trade-offs, and SDD's role in the AI era. gspec is discussed\nonly at the end in comparison with other approaches. Navigation links\nadded to both desktop and mobile menus.\n\nhttps://claude.ai/code/session_01Fsh7zh5ZaDseEfxQb99ypw",
          "is_bot": false,
          "headline": "Add \"What is SDD?\" educational page to the pages site",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-04-15T20:54:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "82d30d96fca28ada62fec464b214a38d26c5bd43",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Uncheck all checkboxes when saving specs for v1.13.1",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-14T01:19:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0d847c11300ebe211069757a446e8e3841a23204",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add save & restore documentation to README",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-13T23:22:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "46b51b3e4443098496687f6ac7aba5d962207a05",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Replace starter templates with save & restore spec library for v1.13.0",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-13T23:20:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bacdc1842a374b0e26ddc4667070c346b1b39b19",
          "body": "…ing for v1.11.0\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add implementation guardrails to prevent silent PRD requirement skipp…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-13T16:58:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4a4bbf4529fed3c315ae31cfd674876bf98de83e",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Auto-create GitHub release on release commits in CI pipeline",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-13T16:23:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "56b6d6db56c46101f1785169e9ff0f090c6d1cdb",
          "body": "…ile guidance for v1.10.0\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Always-on spec sync, streamlined starter setup, and post-install prof…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-10T21:51:42Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ac907389fc963cff2c6be1607b75a447d257e4c9",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add Open Code support and fix README migration false positive for v1.9.0",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-04-02T18:03:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1c6dca98b94f5d6f2a9a77b80b4bd0ba712fba2b",
          "body": "…r v1.8.0\n\nThe installer now offers pre-built starter templates during npx gspec so new projects can bootstrap with practices, stack, style, and feature specs. Also clarifies document ownership boundaries (stack owns test tools and CI/CD technology, style owns icon libraries) and adds the starters page to the documentation site.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add starter template seeding and document authority clarifications fo…",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-29T00:30:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f0d8371b904cff038d312b9d17b0e6a2de634443",
          "body": null,
          "is_bot": false,
          "headline": "Added script for umami tracking to github pages",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-26T23:01:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7d79e316ee73f876812a516d7b4a161d1c8370f9",
          "body": "The feature command now handles both single features and large bodies of\nwork. If the user's request is small, it produces one PRD. If it's large\nenough to warrant decomposition, it proposes a multi-feature breakdown\nfor approval before generating individual PRDs. The separate epic command\nand gspec\n[…]\n/releases.astro with full version history from git tags\n- Added Releases link to site navbar, mobile menu, and footer\n- Bumped version to 1.7.0\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Merge epic into feature command and add releases page for v1.7.0",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-14T21:00:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cf02a4ab5d75059f1b0bd16ed0ff23b92489a884",
          "body": null,
          "is_bot": false,
          "headline": "Removed double border from codeblocks on site",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T17:22:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cfe618c042cfede9a3779f92f8cedf1eac499c8d",
          "body": null,
          "is_bot": false,
          "headline": "Fixed website styling",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T17:17:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bb30063613b4cbb1b774fc1a6110ef65f175705c",
          "body": null,
          "is_bot": false,
          "headline": "Removed base path",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T16:51:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a8ba09ce14bbf1e64f9e8d62faa3f59ef697b42",
          "body": null,
          "is_bot": false,
          "headline": "rectivied path issue",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T04:22:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "323efff79abd961578f6287e1ded3204837d8bba",
          "body": null,
          "is_bot": false,
          "headline": "Updated styling and routing on pages site",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T04:18:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0c2a988b3c4f81465501542854922722ae16ff06",
          "body": "Upgrade Node.js to 22 in CI, add deploy-pages workflow job for Astro site,\nadd gspec spec documents (profile, architecture, stack, style, practices,\nfeatures), and add Astro-based pages site for documentation.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add GitHub Pages deployment and gspec documentation site",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T04:10:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8665499a036d985dbf170d8f4653ad3c12d4df8c",
          "body": null,
          "is_bot": false,
          "headline": "Added installed gspec skills to gitignore",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T02:46:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d39daf68cf7fb85fca00424e1ba23658acb04823",
          "body": null,
          "is_bot": false,
          "headline": "UPdated gitignore",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T02:45:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0a98f8469f478d3b43a4d0342a9c5e025475793",
          "body": "The .claude/, .cursor/, and .agent/ directories were created by running\ngspec inside its own repo. These are install-time outputs (duplicates of\ndist/) and should not be tracked.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Remove install artifacts and gitignore platform directories",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T02:39:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f1318506f0816842cc27ddb93c539c6ceee7a0bf",
          "body": "Replace explicit gspec-dor and gspec-record skills with passive spec-sync\ninstructions that are installed into each platform's always-on rules file\n(CLAUDE.md, .cursor/rules/gspec.mdc, AGENTS.md, .agent/rules/gspec.mdc).\nThe installer now prompts users to enable spec-sync after skill installation,\ndefaulting to yes. Re-installs cleanly replace the existing section.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add automatic spec-sync and remove dor/record commands for v1.6.0",
          "author_name": "Greg Ball",
          "author_login": "gballer77",
          "committed_at": "2026-03-13T02:32:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        }
      ],
      "releases_count": 36,
      "commits_last_year": 142,
      "latest_release_at": "2026-07-26T03:28:25Z",
      "latest_release_tag": "v2.6.0",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 16,
      "days_since_latest_release": 2,
      "mean_days_between_releases": 0.4
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": 28,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "gspec",
          "exists": true,
          "license": "MIT",
          "keywords": [],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/gspec",
          "is_deprecated": false,
          "latest_version": "2.6.0",
          "repository_url": "https://github.com/gballer77/gspec",
          "versions_count": 35,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 1434,
          "first_published_at": "2026-02-12T23:57:28.390000Z",
          "latest_published_at": "2026-07-26T03:28:45.840000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 2
        },
        {
          "name": "pages",
          "exists": true,
          "license": null,
          "keywords": [
            "angular",
            "2lemetry"
          ],
          "ecosystem": "npm",
          "matches_repo": false,
          "registry_url": "https://www.npmjs.com/package/pages",
          "is_deprecated": false,
          "latest_version": "0.0.16",
          "repository_url": "https://github.com/m2mIO/pages",
          "versions_count": 14,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 1850,
          "first_published_at": "2013-08-11T18:15:57.754000Z",
          "latest_published_at": "2013-10-14T20:22:29.532000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 4669
        }
      ]
    },
    "popularity": {
      "forks": 2,
      "stars": 6,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-05-28",
            "count": 1
          },
          {
            "date": "2026-06-05",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 2,
        "total_forks": 2
      },
      "star_history": null,
      "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": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "website/tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 81308,
      "source_files_sampled": 44,
      "oversized_source_files": 2,
      "agent_instruction_files": [
        "CLAUDE.md",
        "website/CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 5570
    },
    "dependencies": {
      "manifests": [
        "package.json",
        "website/package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 8,
        "malicious_count": 0,
        "assessed_package": "npm:gspec@2.6.0",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@clack/prompts",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.7.0"
        },
        {
          "name": "chalk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.6.2"
        },
        {
          "name": "commander",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^11.1.0"
        },
        {
          "name": "@tailwindcss/typography",
          "manifest": "website/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.5.19"
        },
        {
          "name": "@tailwindcss/vite",
          "manifest": "website/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.2.1"
        },
        {
          "name": "astro",
          "manifest": "website/package.json",
          "ecosystem": "npm",
          "version_constraint": "^6.0.4"
        },
        {
          "name": "tailwindcss",
          "manifest": "website/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.2.1"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 14,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "gballer77",
          "commits": 120,
          "avatar_url": "https://avatars.githubusercontent.com/u/84363550?v=4"
        },
        {
          "type": "User",
          "login": "claude",
          "commits": 19,
          "avatar_url": "https://avatars.githubusercontent.com/u/81847?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.863
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 6,
            "reason": "project has 2 contributing companies or organizations -- score normalized to 6",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 2,
            "reason": "dependency not pinned by hash detected -- score normalized to 2",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "28 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "04dfc9cd3ab7d627f5f5f2fc1347af07494160b5",
        "ran_at": "2026-07-28T07:53:45Z",
        "aggregate_score": 3.7,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-26T03:28:48Z",
      "oldest_open_prs": [
        {
          "number": 12,
          "created_at": "2026-05-21T23:18:27Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 13,
          "created_at": "2026-05-28T16:55:33Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-20T22:16:00Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/gballer77/gspec",
    "host": "github.com",
    "name": "gspec",
    "owner": "gballer77"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 58,
      "inputs": {
        "security": 50,
        "vitality": 85,
        "community": 35,
        "governance": 55,
        "engineering": 58
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 85,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "commits_last_year": 142,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 16
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "16/52 weeks with commits",
                "points": 11.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 16
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "142 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 142
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 36,
              "latest_release_tag": "v2.6.0",
              "releases_from_tags": false,
              "days_since_latest_release": 2,
              "mean_days_between_releases": 0.4
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "36 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 36
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 2 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.4 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.4
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 35,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 11,
            "inputs": {
              "forks": 2,
              "stars": 6,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "6 stars",
                "points": 11.3,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "2 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "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
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 53,
            "inputs": {
              "packages": [
                "gspec"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 1434
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "1,434 downloads/month across npm",
                "points": 42.1,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 1434,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 55,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 21,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.863
            },
            "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 86% of commits",
                "points": 3.1,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 86
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 2 contributing companies or organizations -- score normalized to 6",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 72,
            "inputs": {
              "merged_prs": 14,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "14/14 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 14,
                      "decided": 14
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 42,
            "inputs": {
              "followers": 5,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "gballer77",
              "public_repos": 11,
              "account_age_days": 1897
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "5 followers of gballer77",
                "points": 5.6,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 5,
                      "login": "gballer77"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "11 public repos, account ~5 yr old",
                "points": 18.2,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 11
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 5
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "gspec"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 2
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 2 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "35 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 35
                    }
                  }
                ],
                "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": "moderate",
        "name": "Engineering Quality",
        "value": 58,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "1 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 50,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 37,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 3.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 not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 2 contributing companies or organizations -- score normalized to 6",
                "points": 1.5,
                "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": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 2",
                "points": 1,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "28 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the npm:gspec@2.6.0 runtime dependency closure — what installing the published package pulls in — 8 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:gspec@2.6.0",
                  "assessed": 8
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 8,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "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": 8,
              "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": 70,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.83,
              "agent_instruction_files": [
                "CLAUDE.md",
                "website/CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 5570
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md, website/CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md, website/CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "83 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 83,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "website/tsconfig.json"
              ],
              "agent_commit_share": 0.55,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "website/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "website/tsconfig.json"
                    }
                  }
                ],
                "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": "55 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 55,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 2",
                "points": 2,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 80,
            "inputs": {
              "primary_language": "JavaScript",
              "largest_source_bytes": 81308,
              "source_files_sampled": 44,
              "oversized_source_files": 2
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "JavaScript with type-check config (website/tsconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "website/tsconfig.json",
                      "language": "JavaScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "2/44 source files over 60KB",
                "points": 52.5,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 44,
                      "oversized": 2
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "npm package 'pages' points at a different repository (https://github.com/m2mIO/pages); excluded from ecosystem scoring",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-28T07:53:50.762922Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/g/gballer77/gspec.svg",
  "full_name": "gballer77/gspec",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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