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

achird-labs / rift-node

Official Node.js/TypeScript SDK for Rift — typed mocking DSL, embedded (koffi FFI) + remote + spawn transports, Vitest/Jest testkit

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

achird-labs/rift-node 的健康指数为 100 分中的 57 分,处于「中等」区间。 其得分最高的类别是Engineering Quality(86/100),最低的是Security(31/100)。 最近一次更新在 6 天前。 近期的大部分工作由 1 位贡献者完成。

57
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

1 关注者8 个公开仓库始于 2026年7月

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

软件包生态系统

注册表软件包版本月下载量版本数最近发布标签
npm@rift-vs/rift0.15.04,813428 天前mountebankmockstubtestdoublechaosengineeringriftservice-virtualizationapi-mocking
npm@rift-vs/rift-embedded0.15.080268 天前

按类别列示的指标

活力

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

67中等 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 6 天前
3.5/36提交节奏 — 52 周中有 5 周有提交
16.1/18提交量 — 最近一年 61 次提交
0/10OpenSSF Scorecard:Maintained — project was created within the last 90 days. Please review its contents carefully
所用输入
commits_last_year61
human_commit_share1
days_since_last_push6
active_weeks_last_year5

发布纪律

84良好
评分方式
27/27有发布版本 — 已发布 1 个发布版本
36/36发布时效 — 最近一次发布版本于 8 天前
12.6/27发布节奏 — 节奏未知(仅一次发布)
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count1
latest_release_tagv0.15.0
releases_from_tags
days_since_latest_release8
mean_days_between_releases
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

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

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

社区健康

70良好
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
18/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
评分方式
50/80月度下载量 — npm 合计每月 5,615 次下载
0/20注册表被依赖数 — 该生态系统不报告此项
所用输入
packages@rift-vs/rift, @rift-vs/rift-embedded
dependents
ecosystemsnpm
total_downloads
monthly_downloads5,615
已排除计分(无数据或不适用):注册表被依赖数。 其余权重已重新归一化。

可持续性与治理

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

53中等 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
0/22.5提交分布 — 头号贡献者编写了 100% 的提交
1.4/13.5贡献者广度 — 1 位贡献者
0/10OpenSSF Scorecard:Contributors — project has 0 contributing companies or organizations -- score normalized to 0
所用输入
bus_factor1
contributors_sampled1
top_contributor_share1
评分方式
44.6/46.8议题解决 — 95% 的议题已关闭
37.5/38.3PR 接受 — 已裁定的 PR 中 51/52 已合并
0/15OpenSSF Scorecard:Code-Review — Found 1/30 approved changesets -- score normalized to 0
所用输入
merged_prs51
open_issues2
closed_issues41
issue_closed_ratio0.953
closed_unmerged_prs1
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
2.2/25所有者影响力 — achird-labs 有 1 位关注者
7/25既往记录 — 8 个公开仓库,账户约 0 年
所用输入
followers1
owner_typeOrganization
is_verified
owner_loginachird-labs
public_repos8
account_age_days11
评分方式
25/25已发布且可解析 — npm 上有 2 个软件包
35/35发布时效 — 最近一次发布于 8 天前
20/20版本历史 — 42 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packages@rift-vs/rift, @rift-vs/rift-embedded
ecosystemsnpm
any_deprecated
min_days_since_publish8

工程质量

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

86优秀 · 占总体的 20%

工程实践

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

文档

90优秀
评分方式
30/30README
25/25文档目录
15/15文档 / 主页站点 — https://achird-labs.github.io/rift-node/
10/10仓库描述
0/10主题标签
10/10Wiki
所用输入
topics
has_wiki
homepagehttps://achird-labs.github.io/rift-node/
has_readme
has_docs_dir
has_description

安全

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

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

安全态势

31存在风险
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 1/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
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
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
2.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 5
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — 无数据
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 22 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate3.1
已排除计分(无数据或不适用):signed_releases。 其余权重已重新归一化。

AI 就绪度

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

57中等 · 占总体的 0%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 61 次人类提交中有 58 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.951
agent_instruction_files
agent_instruction_max_bytes
评分方式
0/18一条命令的引导启动
22/22自动化测试
11/11Lint / 格式化配置 — .eslintrc.cjs
11/11静态类型检查 — packages/rift-core/tsconfig.json, packages/rift-embedded/tsconfig.json
10/10可复现环境 — lockfile
0/10已体现的代理实践 — 最近 61 次提交中没有代理编写的提交
0/8自动化维护 — 未观察到自动依赖更新
5/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 5
所用输入
has_nix
has_tests
lockfilespackage-lock.json
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configspackages/rift-core/tsconfig.json, packages/rift-embedded/tsconfig.json
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
评分方式
45/45可类型检查的代码 — TypeScript(静态类型)
55/55可控的文件大小 — 采样的 117 个源文件中有 0 个超过 60KB
所用输入
primary_languageTypeScript
largest_source_bytes42,365
source_files_sampled117
oversized_source_files0

机器可读接口

40存在风险
评分方式
0/40API 模式(OpenAPI/GraphQL/proto)
0/20MCP 服务器
40/40可运行示例 — examples
所用输入
example_dirsexamples
has_mcp_signal
api_schema_files

关键数据

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

数据采集警告

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

更多细节

OpenSSF Scorecard 3.1 / 10
3.1综合

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 1/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
5Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 5
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
不适用Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities22 existing vulnerabilities detected
直接依赖 1
注册表软件包版本约束清单文件
npmkoffi^2.9.0packages/rift-embedded/package.json
全部依赖 未采集

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

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 569,
      "has_wiki": true,
      "homepage": "https://achird-labs.github.io/rift-node/",
      "languages": {
        "Shell": 1875,
        "JavaScript": 19897,
        "TypeScript": 756619
      },
      "pushed_at": "2026-07-22T23:34:15Z",
      "created_at": "2026-07-09T21:36:42Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-21T14:03:28Z",
      "description": "Official Node.js/TypeScript SDK for Rift — typed mocking DSL, embedded (koffi FFI) + remote + spawn transports, Vitest/Jest testkit",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "master",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "Organization",
      "login": "achird-labs",
      "company": null,
      "location": null,
      "followers": 1,
      "avatar_url": "https://avatars.githubusercontent.com/u/306492270?v=4",
      "created_at": "2026-07-18T12:33:23Z",
      "is_verified": null,
      "public_repos": 8,
      "account_age_days": 11
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.15.0",
          "kind": "minor",
          "published_at": "2026-07-21T13:13:02Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "38680683f937f89e3dd6b23f4161e9f46cd9a756",
          "body": "rift-node had no docs site and a 17-line root README that only described the\nworkspace layout, while the engine and the Java SDK both publish full sites. A\nreader arriving from npm had nowhere to go.\n\nBuild the site the same way the engine repo does (Jekyll + just-the-docs, GitHub's\nown builder, no \n[…]\non someone remembering\nto register a directory. The landing-page hero is embed-checked against\nexamples/hero.ts rather than hand-copied, which is what took the checker from 10\nverified snippets to 11.",
          "is_bot": false,
          "headline": "docs: publish a documentation site and rewrite the READMEs (#93)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-21T13:30:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d39a5b223e68aa801a1dce070de922c5702c2586",
          "body": "The published `@rift-vs/rift@latest` is 0.14.0, cut from the old EtaCassiopeia/rift\nrepo. This repo's package.json still said 0.12.1, so releasing as-is would have moved\nnpm's `latest` tag *backward* and silently downgraded every consumer onto a different,\nolder codebase. Version both workspaces in \n[…]\nstall-time postinstall download.\n\nVerified: both tarballs stamped 0.15.0 and now carry LICENSE + README (npm publish\n--dry-run), 445/445 unit tests, lint/typecheck/docs:check/typecheck:examples green.",
          "is_bot": false,
          "headline": "chore(release): prepare the first achird-labs release as 0.15.0 (#92)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-21T12:57:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "05e938853ba0403fe6f490026f7c1c0c20216c34",
          "body": "…e affinity-LB pattern (#91)\n\nThe numeric/boolean header 400 (engine rift#754) is fixed in engine v0.15.0\n(rift#757), but stays documented as a version-scoped compat note because\nbinary resolution can still land on an older engine via a PATH install,\nbinaryPath/RIFT_BINARY_PATH, or a pinned version:\n[…]\ned.\n\nAdds the sanctioned multi-instance answer (independent nodes behind a\nsticky/affinity LB keyed on flow id) and drops promissory roadmap language\nabout engine-side distributed support.\n\nCloses #85",
          "is_bot": false,
          "headline": "docs(migration): version-scope the numeric-header gap and document th…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-21T12:39:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cb632d22a9af1d541ca1c4f8696b11b2dbc44d88",
          "body": "Bumps the rift engine pin from 0.14.0 to 0.15.0 via scripts/bump.sh (the single source of truth for this repo's pin literals).\n\nCo-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
          "is_bot": false,
          "headline": "chore(deps): bump rift engine to 0.15.0 (#90)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-21T12:08:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "176ccc9ff5f0fd9e0c74881b113da57241ef23d7",
          "body": "The engine, the sibling SDKs and this repo all now live in the achird-labs\norg. Two of these were already broken rather than merely stale:\n\n- engine-bump.yml was half-migrated - it passed upstream_repo:\n  achird-labs/rift while still calling the reusable dep-bump workflow from\n  EtaCassiopeia/rift-j\n[…]\nnly via GitHub's redirect. Release-asset redirects are not\n  something to depend on for a download path that verifies SHA-256.\n\nThe npm scope (@rift-vs) is unchanged, so nothing changes for consumers.",
          "is_bot": false,
          "headline": "chore: repoint at achird-labs (#89)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-20T01:13:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9a93306da20778dab1e6cfb1970a06a82ba83e2e",
          "body": "…d) (#88)\n\nThe engine repo EtaCassiopeia/rift was transferred to achird-labs/rift; GitHub\nredirects the old name but the dep-bump release poll should target the canonical\nrepo directly rather than rely on API redirects. Also the target for the new\nimmediate-dispatch trigger added on the engine side.",
          "is_bot": false,
          "headline": "ci(engine-bump): point upstream_repo at achird-labs/rift (repo rename…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-19T00:48:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "41bfd78ce77c9dc20ce04cf816af55fe9d63aaaa",
          "body": "…usl build on Alpine (#84) (#86)\n\n* fix(spawn): version-probe PATH hits and select the musl build on Alpine\n\nTwo binary-resolution robustness gaps found while building a Mountebank->Rift\ncontainer drop-in test.\n\n1. `mb` is in the PATH probe list for migration ergonomics, but Homebrew's\n   Mountebank\n[…]\nest hardcoded the PATH name `mb`, but on Windows the\nresolver probes `mb.exe`, so lookupPath never returned the hit and `probed` was\nempty. Match both names, mirroring the existing rift/rift.exe test.",
          "is_bot": false,
          "headline": "fix(spawn): version-probe PATH hits (no silent Mountebank) + select m…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-18T12:42:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e83f14845c12d9894c874cf1a2d3b65de9a498eb",
          "body": "…dep-bump (#83)\n\nengine-bump.yml -> thin caller of EtaCassiopeia/rift-java/.github/workflows/dep-bump.yml@master; scripts/bump-engine.sh renamed scripts/bump.sh (+ --current). Bumps only DEFAULT_ENGINE_VERSION. Behavior-preserving. Part of rift-java#156.",
          "is_bot": false,
          "headline": "refactor(ci): convert engine-bump to a caller of the shared reusable …",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-18T02:48:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a405b71001ca30561630c58714dba90864e24988",
          "body": "The engine already reports numberOfRequests (journal-backed, counts even with\nrecordRequests off). This adds a regression guard asserting it is present and\nincrements (0 -> 2) on GET /imposters/:port and the list form, so a future\nchange that renames/drops/gates the field is caught before it reaches a\nconsumer's analytics as undefined.\n\nCloses #78",
          "is_bot": false,
          "headline": "test(compat): pin numberOfRequests on the imposter wire views (#82)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-18T02:41:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1c434a41180e99a73181ce3f4e26d622d2dcd322",
          "body": "…ng (#81)\n\ncreate() previously accepted-and-ignored impostersRepository/redis, silently\nrunning an in-memory single-process server — the \"config silently dropped\"\nanti-pattern. It now throws UnsupportedCreateOptionError before spawning,\nnaming the option and the supported alternatives (datadir for persistence,\nper-imposter flowState() for distributed scenario state).\n\nCloses #76",
          "is_bot": false,
          "headline": "fix(compat): fail loud on impostersRepository/redis instead of ignori…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-18T02:34:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ecaa81b897fd19f228b5c72012ef342c05751e9e",
          "body": "…#79)\n\nengine-bump.yml (daily poll of EtaCassiopeia/rift -> chore/engine-<ver> PR bumping DEFAULT_ENGINE_VERSION via scripts/bump-engine.sh) + auto-release.yml (workflow_run on green CI -> squash-merge + inline npm publish, package.json versioned in lockstep). First release human-gated; reuses NPM_TOKEN; exactly-once publish.",
          "is_bot": false,
          "headline": "feat(ci): auto-bump engine and cut an npm patch release on green CI (…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-18T02:23:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "47ebb4de4f107f83d66bc303450092ad2fd06966",
          "body": "…arity (#80)\n\ncreate({ datadir }) now maps to the engine's --datadir flag, matching\nmb.create({ datadir }) — imposters created via the admin API persist as\n{port}.json and reload on restart, bringing the compat path to parity with\nrift.spawn({ datadir }). Adds a migration.md \"Persistence & distributed state\"\nsection documenting the path for custom impostersRepository deployments.\n\nCloses #77",
          "is_bot": false,
          "headline": "feat(compat): expose datadir in create() for Mountebank persistence p…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-18T02:22:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f37e99e4a8e413b34e5ff0d0968ac7ebd4de810b",
          "body": "…-assigns (avoids host port collisions) (#74)\n\nthe mb conformance fixtures pin port 4545; the replay driver bound it verbatim, so any other host process serving 4545 could answer the fetch with a confusing right-status/empty-body mismatch (root cause of a long-standing \"cold-run replay flake\"). repl\n[…]\ne separate DSL-coverage gate. Adds a koffi-free unit gate (port stripped before create) and a deterministic embedded-lane gate (squatter on an ephemeral port; replay must still hit the real imposter).",
          "is_bot": false,
          "headline": "test(conformance): drop the fixture port in replay so the engine auto…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-18T00:09:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "957cfbfeda56f9b6d5956de526edd603ad857cab",
          "body": "…epAlive for standalone servers (#73)\n\nworker was unref'd unconditionally, so a bare script's awaited call could be dropped when the loop drained (Node exit 13, unsettled top-level await). Now #call refs the worker on the 0->1 pending transition and unref happens when the map drains (including error\n[…]\nworker while the engine is open — the standalone Mountebank-style mock-server shape. Gates: 7 fake-worker unit tests + 3 real child-process integration tests in the required embedded lane. Closes #70.",
          "is_bot": false,
          "headline": "fix(embedded): hold the event loop during in-flight FFI calls; add ke…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T23:51:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "75dc0f6345703c9ae8695fc8c8e147bc55a44854",
          "body": "…m workspaces) (#71)\n\nConverts the repo to npm workspaces: packages/rift-core (@rift-vs/rift, unchanged publish name) + packages/rift-embedded (@rift-vs/rift-embedded, koffi as a REAL dependency), root is a private shell delegating build/test/lint/docs scripts; core builds first.\n\nCore reaches embed\n[…]\nish.yml stamps+publishes BOTH workspaces in lockstep; ci.yml cdylib cache keys on the embedded manifest; debug-lane patch paths updated. Docs (sdk-api §2/§8.2, READMEs, examples) updated.\n\nCloses #39.",
          "is_bot": false,
          "headline": "build(embedded): extract src/embedded into @rift-vs/rift-embedded (np…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T23:22:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9c023edb271e2ae5a37fd64d9c17c99576b73e88",
          "body": "…te (#69)\n\nThe #53 segfault and subsequent #62/#63/#65 follow-ons are fixed. The\nembedded-conformance lane is green on ubuntu+macos (run 29617312113), so\nwe can drop the job-level continue-on-error flag and make it a required\nM8 gate.\n\nThe fetch-step's continue-on-error (cdylib-404 self-skip) is pre\n[…]\nd.\nThe embedded-conformance-windows experimental job and embedded-segfault-debug\nlane remain unchanged.\n\nUpdated .github/workflows/ci.yml and docs/design/sdk-api.md (removed\n#44 from open-follow-ups).",
          "is_bot": false,
          "headline": "test(embedded): make the embedded conformance lane the required M8 ga…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T22:30:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "119f3ccfa8c5c412682a9e5865f5fb7c1ac6700e",
          "body": "… documented signature (#68)\n\nRestores the §5.9 documented `StubBuilder | wire.Stub` signature that was\nregressed by #47. The `.stub()` method now accepts builder-or-raw Stub objects,\nmirrors how `create()`/`toWireStub` accept both forms, and fixes the\n`TypeError: s.build is not a function` error when injecting raw stubs.\n\nFixes: #65\nVerified: typecheck, eslint, full unit suite (480 tests pass, 3 new)",
          "is_bot": false,
          "headline": "fix(dsl): let imposter().stub() accept raw Stub objects, matching its…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T22:15:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bdcd4f0a4d55f3effc2295bc1bab4afccd25dceb",
          "body": "…instead of failing on literal port 0 (#67)\n\nCloses #63",
          "is_bot": false,
          "headline": "test(embedded): omit port in smoke createImposter so it auto-assigns …",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T21:39:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "faa2da85f47a83ca8ece1c66b5b1b35a6b3f6e9c",
          "body": "…ng works on Node 20/22 (#64)\n\nJest's vm context lacks dispose symbols on Node 20/22, which broke the embedded\nintegration suites once #53 stopped masking them. This adds a setup file to\npolyfill both Symbol.asyncDispose and Symbol.dispose before tests run.",
          "is_bot": false,
          "headline": "test(embedded): polyfill Symbol.asyncDispose for jest vm so await usi…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T21:30:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "71cceef51bdf8d0314cc3df48a424f07e1a2d4ca",
          "body": "…-1) (#53) (#61)\n\n`rift.embedded()` hard-crashed (SIGSEGV) on every platform the moment the FFI\nran, at init while decoding rift_build_info. Root cause: `koffi.decode(ptr,\n'string')` on a raw `char*` treats the argument as a pointer-TO-a-string\n(char**) and dereferences once too many — it reads the \n[…]\nst the released v0.12.0 cdylib: the `'string'` form\nSIGSEGVs; `('char', -1)` decodes rift_build_info and a rift_apply_config +\nrift_free cycle (x5) cleanly. koffi.d.ts gains the 3-arg decode overload.",
          "is_bot": false,
          "headline": "fix(embedded): decode FFI char* results with koffi.decode(ptr,'char',…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T21:03:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0f9e941d096d05be10b89896a5fb8c50b7c027fe",
          "body": "The previous run's trace file came up empty even though the crash reproduces\nand worker_threads demonstrably inherit process.env under jest — so the\nfile-only channel wasn't the right signal. Make the diagnostic robust:\n\n- debug-trace.ts: traceFfi now also writes each label to stderr via\n  writeSync\n[…]\non macOS cat the symbolicated .ips inline (it holds the caller the koffi\n  trampoline hides) and read $x0 as a string.\n\nEnv-gated and inert in production; native-call.ts stays pure. #53 stays blocked.",
          "is_bot": false,
          "headline": "ci(embedded): robust FFI trace (stderr) + deeper core dump for #53 (#60)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T20:34:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1da164837b0265bf713de21351a103aa5be280ca",
          "body": "…nly) (#59)\n\nThe previous run showed the crash lands right as the first embedded engine\ninits — before any call and before rift_build_info/rift_start — so the\nper-call/no-decode traces stayed empty and couldn't name it. Extend the\nenv-gated trace to the koffi binding phase so the trace file's last l\n[…]\nthe crash precedes the first traced point — this pins\nwhether it's koffi.load, a specific symbol bind, or a later call. Env-gated and\ninert in production; native-call.ts stays pure. #53 stays blocked.",
          "is_bot": false,
          "headline": "ci(embedded): trace koffi bind phase to pin the #53 segfault (debug-o…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T20:13:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ba3276a4b298b2757250bc2d800fb6d57d9012f8",
          "body": "…lt debug lane (#53) (#58)\n\nThe first debug-lane run localized the crash to `strlen` on a worker thread at the\nkoffi boundary, and refuted H2 (no-free crashes identically). Extend the lane to\npin the exact symbol and isolate the decode path:\n\n- Per-symbol trace (worker.ts): when RIFT_FFI_DEBUG_TRACE\n[…]\nult-decode\n  path; if it persists -> argument marshalling.\n\nBoth hooks are env-gated and inert in production (native-call.ts stays pure).\nTrace file added to the uploaded artifacts. #53 stays blocked.",
          "is_bot": false,
          "headline": "ci(embedded): add no-decode mode + per-symbol trace to the FFI segfau…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T19:51:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "df6b9891940d33ca83aa93569acebf1436461c1d",
          "body": "…re (#53) (#57)\n\nThe embedded-conformance lanes only report \"Segmentation fault\" with no frame,\nwhich is not enough to root-cause #53. Add a debug-only job that reproduces the\ncrash under core-dump capture and extracts a native backtrace.\n\n- Opt-in only: runs on workflow_dispatch or a `[ffi-debug]` \n[…]\n test log, node report, macOS .ips crash report, and gzipped core as artifacts.\n\nDoes not change the shipped code or any gating lane; #53 stays blocked until a\ncaptured backtrace identifies the fault.",
          "is_bot": false,
          "headline": "ci(embedded): add opt-in FFI segfault debug lane with core-dump captu…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T19:24:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "93c3ea8e69bb7f12650622a873fbc10fe4430d7a",
          "body": "…s (#56)\n\nAdded exported type alias AnyStubBuilder = StubBuilder<Record<string, string>>\nand widened every stub-consuming position to it (imposter().stub(), scenario().when(),\nRequestMatch, ImposterHandle/SpaceHandle addStub/replaceStubs/updateStub, toWireStub),\nenabling param-typed builders from on\n[…]\nand\nremoved the #47 follow-ups row. Added test/unit/dsl-stub-compose.test.ts (runtime smoke).\n\nVerified: typecheck, typecheck:examples, docs:check, eslint (0 errors), unit suite (477 pass).\n\nFixes #47",
          "is_bot": false,
          "headline": "fix(dsl): let param-typed StubBuilder compose into consuming position…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T18:37:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a2e27646a3f39e02ed6a4022d78d41847072dfe3",
          "body": "The committed node_modules symlink was a mode-120000 entry pointing to an\nabsolute local path, causing ELOOP errors and dangling references across\ndifferent environments. Removed via git rm.\n\nUpdated .gitignore from 'node_modules/' to 'node_modules' to ensure that\nany node_modules symlink, directory, or file is properly ignored, allowing\nnpm ci to function without git status conflicts.\n\nVerified: git ls-files node_modules is empty; npm ci leaves clean status.\n\nCloses #48",
          "is_bot": false,
          "headline": "fix(repo): remove committed node_modules symlink and ignore it (#55)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T18:04:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "19a968cce3634908c2ce3c264169b6608e939636",
          "body": "…lure pending #53 (#54)\n\njest.embedded.config.js remaps src imports to the built dist so worker_threads resolves the real dist/embedded/worker.js; npm run test:embedded; both embedded CI jobs use it. First genuine FFI execution exposed the cross-platform segfault #53, so the lane stays continue-on-error with the required-gate flip documented for when #53 lands. Refs #44, #53.",
          "is_bot": false,
          "headline": "test(embedded): conformance lane runs against built dist, allowed-fai…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T03:24:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3d9cdf4344df09e4b3883fe4918c5f1c56ff42b6",
          "body": "…#52)\n\nThree conformance fixtures tag stubs with a bare scenarioName (grouping\nonly, no required/new state), which the scenario() FSM builder cannot\nexpress without emitting transitions. Add StubBuilder.inScenario(name)\nfollowing the id()/inSpace() slot pattern, reconstruct\nauthentication-api, featu\n[…]\n raw({ stubs }) workaround), and shrink\nfromJsonOnly to just latency-testing.json (wait:{inject}, fromJson-only\nby #23 design). The canonical API reference's #36 gap notes flip to\nshipped.\n\nCloses #36",
          "is_bot": false,
          "headline": "feat(dsl): inScenario() — bare scenarioName grouping without an FSM (…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T02:59:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "83e7e11e60947c281399a3af2ac1c9189c2960da",
          "body": "…JSON bodies (#51)\n\nUnknown request-field names in a predicate (exists: { pathh } or an\noperator FieldMatch) threw nothing and resolved as a silent non-match —\nnow they throw UnsupportedPredicateError naming the field, mirroring how\noperator typos already fail. A jsonpath or object-equals predicate \n[…]\nnote (verdict unchanged,\nfail-closed). Malformed matches/except patterns surfaced as raw\nSyntaxError — regex compilation now rethrows as InvalidDefinition with\nthe original error as cause.\n\nCloses #33",
          "is_bot": false,
          "headline": "fix(verify): fail loudly on field typos and bad regexes, explain non-…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T02:44:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "edf6d2805e0310bc21140bdb910cf92eb0a87c11",
          "body": "… host (#50)\n\nThe child's 'error' listener threw inside the emitter, so a spawn failure\n(bad binary path, ENOENT, EACCES) escaped the startup try/catch as an\nuncaught exception and killed the host process. Fold a spawnErrorPromise\ninto the startup race so it rejects catchably, reject promptly on a c\n[…]\nstart so post-startup child errors reach\nserver.on('error') consumers. Spawn and binary resolution are injectable\n(CreateDeps) so the failure paths are unit-testable without a real binary.\n\nCloses #28",
          "is_bot": false,
          "headline": "fix(compat): reject create() on spawn failure instead of crashing the…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T02:32:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d9de2852d5dd673f943875a63dd92e2cf9f67917",
          "body": "…#49)\n\nThe 2026-07-09 design doc's every slice has shipped, so re-frame it as the\nliving reference: describe the shipped single-package layout (koffi\noptionalDependency, ./embedded subpath; split deferred to #39), correct the\nC-ABI count to 26 symbols, document requests() (#26), annotate the honest\n\n[…]\nnto a delivered\nledger with per-issue PRs plus open follow-ups. Wire the doc's runnable\nsnippets into docs:check by scanning docs/design/*.md and backing §0/§9\nwith embed-checked examples.\n\nCloses #20",
          "is_bot": false,
          "headline": "docs(design): reconcile sdk-api.md into the canonical API reference (…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T02:08:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "195a0a7d18e8bd3be87a7c777c5ca9f5e2c9abcb",
          "body": "…n notes (#46)\n\nRestructures the README (hero typed-DSL quick-start + verify, per-transport quick\nstarts for embedded/spawn/connect/compat, feature tour, corrected env-var table)\nand adds docs/migration.md (a complete Mountebank-JSON ↔ typed-DSL side-by-side\ncovering every operator/behavior/fault/re\n[…]\nmbed marker\nand enforced by scripts/check-docs-embeds.mjs (new docs CI job runs it +\ntypecheck:examples), so snippets can't rot. The rift-side doc redirect is tracked\nupstream as rift#473.\n\nCloses #14",
          "is_bot": false,
          "headline": "docs: quick starts + Mountebank migration guide + monorepo deprecatio…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T00:38:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3319dc57d44a2d5e71da7243179f1367acadcd8b",
          "body": "…eardown, assertReceived (#45)\n\nAdds test-framework glue over the client API: @rift-vs/rift/testkit/vitest\n(riftTest/createRiftTest fixtures — a worker-scoped engine + per-test imposter\nauto-teardown) and @rift-vs/rift/testkit/jest (setupRift beforeAll/afterEach/\nafterAll helpers). Both re-export as\n[…]\nor via transport. vitest stays an optional\npeer, imported only inside the vitest subpath. Adds a 15-test fake-engine gate\n(with a real jest-lifecycle proof) and a README isolation section.\n\nCloses #12",
          "is_bot": false,
          "headline": "feat(testkit): Vitest fixtures + Jest helpers — shared engine, auto-t…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-17T00:14:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "acde544ca782f80942dd8fcea5b17139a8dd3969",
          "body": "…l windows lane (#43)\n\n* test(conformance): corpus over embedded transport + experimental windows lane\n\nExtends the #7 conformance harness to the embedded transport (the driver is\nalready transport-agnostic) and adds CI topology: an embedded-conformance job\n(ubuntu/macos, cdylib via rift-fetch --lib\n[…]\ned dist; the harness needs to run against the build. Mark the\nlinux/darwin lanes continue-on-error (tracking) like the experimental windows lane\nuntil that follow-up lands, so they never block merges.",
          "is_bot": false,
          "headline": "test(conformance): corpus green over embedded transport + experimenta…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T23:48:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f118a607b3430aa2a2963e88525a6cf39efa5612",
          "body": "…e trust helpers (#42)\n\nAdds engine.intercept(options?) → InterceptHandle: serve/forward/redirectTo\nrules, addRule/rules/clearRules, caPem/caFile, exportTruststore, and env() for\nNode trust. A backend seam (InterceptBackend) is adapted per transport —\nembedded over FFI, remote+spawn over the HTTP ad\n[…]\nnamically imported). Adds wire.InterceptRule, RemoteClient intercept routes, the\nspawn --intercept-port flag, a 37-test fake-backend gate, and a self-skipping\nreal-engine integration lane.\n\nCloses #11",
          "is_bot": false,
          "headline": "feat(intercept): TLS-MITM surface — serve/forward/redirectTo, CA, Nod…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T23:19:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e4914dc1c5a0e6a5cdd5ad43129146946c63279d",
          "body": "Wires rift.embedded(options) to return the same RiftEngine as connect/spawn,\nbacked by the embedded worker binding (#8) with the cdylib resolved via #9.\nRuns a version + feature preflight (versionCheck fail/warn/off, requireFeatures)\nand drives an FFI-first EmbeddedAdmin: imposters/stubs/recorded/fl\n[…]\n per process are independent. The embedded module is\ndynamically imported so core stays zero-dep. Adds a 24-test fake-NativeEngine gate\n+ a RIFT_FFI_LIB-gated quick-start integration test.\n\nCloses #10",
          "is_bot": false,
          "headline": "feat(embedded): rift.embedded() wiring + engine-version preflight (#41)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T22:47:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bba9e0ea1a2cdb0fbf3cec59a3cecc5d0a21e173",
          "body": "… discipline (#40)\n\n* feat(embedded): koffi binding for C-ABI v2 — worker-thread last-error discipline\n\nAdds src/embedded (exposed via the ./embedded subpath): a koffi binding for the\nlibrift_ffi C-ABI v2 (26 symbols) run inside a dedicated worker_threads worker so\nevery call is paired with a same-t\n[…]\nync package-lock.json with koffi optionalDependency\n\nCI npm ci failed 'Missing: koffi from lock file' — regenerate the lock so it\nmatches the koffi optionalDependency added for the embedded transport.",
          "is_bot": false,
          "headline": "feat(embedded): koffi binding for C-ABI v2 — worker-thread last-error…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T22:18:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9e92ea79d6e88487dadcd1ca1531d55b322bfbb3",
          "body": "…a cache, manifest download (#38)\n\nAdds src/natives: resolveCdylib (librift_ffi) mirroring the engine-binary\nresolver — RIFT_FFI_LIB/libPath override → sidecar-validated cache → manifest\ndownload with MANDATORY sha256 (no skip flag) → air-gap error with a\ncopy-pasteable manual-install path pointing \n[…]\npped (resolve.ts untouched). Extends bin/rift-fetch with --bin/--lib/\n--version/--classifier. Adds a 26-test injected-IO gate + a network-gated\nintegration test, and a README env-var table.\n\nCloses #9",
          "is_bot": false,
          "headline": "build(natives): cdylib resolution — RIFT_FFI_LIB override, version+sh…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T21:44:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "27d458bcf7fba6de0f6d6538858019deeaaeae64",
          "body": "Adds test/conformance/: a fixture loader (local mb fixtures + the rift#460\nsdk-conformance tarball with sha/air-gap discipline), a replayFixture driver\n(create via fromJson, replay interactions over fetch, strict status/headers/body\nassertions), and a pure DSL-expressibility gate. The gate accounts \n[…]\nonstruction, keeping the gate honest. Failure modes (missing\ncoverage names the fixture; wire mismatch prints a diff) are tested. The replay\nover spawn is binary-gated and self-skips in CI.\n\nCloses #7",
          "is_bot": false,
          "headline": "test(conformance): corpus replay harness + DSL expressibility gate (#37)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T21:17:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "57d0586cee8723640584ecb105aff4b31afb44a2",
          "body": "…rator (#35)\n\nAdds ImposterHandle.requests(opts?) → AsyncIterableIterator<RecordedRequest>:\na polling iterator over an imposter's recorded requests with a monotonic\ncursor (no duplicates), cursor reset on clearRecorded(), an optional client-side\nmatch filter (reusing the verify evaluator), and clean\n[…]\nd) completes the iterator.\nSSE upgrade (rift#461) is a future transparent swap; polling ships now. Adds a\ntest:leaks npm script (--detectOpenHandles) and an 8-case gate + integration test.\n\nCloses #26",
          "is_bot": false,
          "headline": "feat(core): recorded-request async iteration — polling requests() ite…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T20:53:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b9bac15b1dfeb7a33c38fef6395462c88d4f3eb4",
          "body": "…times) with readable diffs (#34)\n\nAdds the verification API: typed RecordedRequest, handle.recorded/clearRecorded/\nverify(match, count) with WireMock-style near-miss diffs, count matchers\n(times/atLeast/atMost/between/never, exported from root), a zero-dep client-side\npredicate evaluator mirroring \n[…]\nUnsupported and operator-less\npredicates throw UnsupportedPredicateError rather than matching silently.\nSpaceHandle scopes by flow id. Adds a 56-case gate + a binary-gated integration test.\n\nCloses #6",
          "is_bot": false,
          "headline": "feat(core): verification API — typed RecordedRequest + verify(match, …",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T20:32:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7360da1783ddaf8ba1d82cb63a2550059209dff0",
          "body": "…ward, _rift config, scenario fixes (#32)\n\nCompletes the imposter builder (https/mTLS, defaultForward, strictBehaviors,\nserviceName/Info, and the imposter-level _rift config: flowState, metrics,\nscriptEngine, registerScript — all merging across calls), adds stub-level\nid/inSpace/routePattern, and fi\n[…]\nebuild rewrite) and respond() is variadic.\ndefaultResponse throws InvalidDefinition (not a plain Error) on a non-is or\nempty response. Adds a 22-test gate (test/unit/dsl-imposter.test.ts).\n\nCloses #24",
          "is_bot": false,
          "headline": "feat(dsl): imposter/stub/scenario completion — HTTPS/mTLS, defaultFor…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T20:01:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e4d0f5eb77d746fe7062e304ab57a4f093f93cc8",
          "body": "…ipt, full proxy (#31)\n\nCompletes the response side of the fluent DSL: full _behaviors (copy/lookup/\ndecorate/shellTransform/wait variants), binary body + multi-value headers +\ntemplated, typed faults (Fault + withFault merge), a Script builder, and a full\nproxy ProxyBuilder. Fixes the silent-drop b\n[…]\n makes invalid response shapes fail loudly with\nInvalidDefinition instead of dropping data. willReturn now appends (response\ncycling). Adds a 34-test gate (test/unit/dsl-response.test.ts).\n\nCloses #23",
          "is_bot": false,
          "headline": "feat(dsl): response completion — behaviors, binary, typed faults, Scr…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T19:46:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "877261d1b11de874388b312ce38ccc714eb3142c",
          "body": "Build expected paths with path.join and the platform binary suffix so the\nextractedBinaryCandidates test passes on Windows CI (path.sep + rift.exe),\nnot just POSIX. Fixes the master CI regression from f3944cf.",
          "is_bot": false,
          "headline": "test(spawn): make extracted-candidate assertions platform-agnostic",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T19:12:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f3944cf48dfbc182ee68cca40caa4aad210d8442",
          "body": "- Probe real release-archive layout (rift-<version>-<target>/bin/rift)\n  so engine downloads succeed; keep legacy locations as fallbacks.\n- Default host to 127.0.0.1 (IP literal) so spawn() no longer aborts on\n  the engine's \"invalid socket address syntax\".\n- Bump DEFAULT_ENGINE_VERSION to v0.14.0; minEngineVersion stays 0.12.0.\n- Name the wire.RecordedRequest _mode?: 'binary' marker (engine >= 0.13.6).",
          "is_bot": false,
          "headline": "fix(spawn): correct engine download layout and default bind host",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-16T19:07:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8a0570c4098f9e8a7e631ec2e052bb5dc04178a7",
          "body": "- Immutable Matcher value objects with equals/deepEquals/contains/startsWith/endsWith/matches/exists/notExists predicates\n- caseSensitive/keyCaseSensitive/except/jsonpath/xpath modifier chains\n- req.{method,path,body,header,query} binders replacing field-first helpers\n- StubBuilder withMethod/withPa\n[…]\nex path predicate\n- Compile-time PathParams<P> type with path parameter extraction\n- and/or/not logical operators for predicate composition\n- injectPredicate for custom predicate functions\n\nCloses #22",
          "is_bot": false,
          "headline": "feat(dsl): matcher grammar — full predicate coverage (#30)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-10T03:00:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "20e750e4a47aad1e454ab9ab9543b6007aaaf64f",
          "body": "…lient API (#29)\n\n* feat(core): RiftEngine facade + ImposterHandle — transport-agnostic client API\n\n- new src/engine.ts with AdminApi interface + Engine facade + ImposterHandle/SpaceHandle/FlowStateHandle implemented once over AdminApi\n- RemoteClient now implements the full admin route table (stub s\n[…]\nbility.\nAlso, toWireImposter now defaults protocol to 'http' when unset, so spawn/remote transports\ncan successfully create imposters without explicit protocol (fixes integration test on real engine).",
          "is_bot": false,
          "headline": "feat(core): RiftEngine facade + ImposterHandle — transport-agnostic c…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-10T02:40:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "62d39f6eaa946fb2eb826ebd111fd3e17e9edea5",
          "body": "…emoval, errors module, exports map, ESM-only (#27)\n\n* chore(core): export hygiene + legacy retirement\n\n- canonical src/errors.ts (full RiftError hierarchy)\n- root exports stripped of legacy weak types (wire model via `wire` namespace)\n- axios removed → zero runtime deps (fetch-based compat poll)\n- \n[…]\nution\n\nThe exports-build test failed on Windows runners with ENOENT when trying\nto spawn 'npm' directly. Using execSync with shell: true allows the\nsystem shell to resolve npm.cmd on Windows properly.",
          "is_bot": false,
          "headline": "chore(core): export hygiene + legacy retirement — root types, axios r…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-10T02:00:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "850757108d6cffbc9b15060f908d653601232c29",
          "body": "…-node#20\n\nSnapshot of the approved API design (engine facade, matcher DSL, verification,\nembedded/intercept/testkit) so the repo carries the reference the M7/M8 issues\nimplement against.",
          "is_bot": false,
          "headline": "docs(design): complete SDK API surface — canonical reference for rift…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-10T01:21:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "608439c01003bba007b950f78f35f72f586fd399",
          "body": "… (#19)\n\n* feat(core): spawn transport rework + Mountebank-compat create() layer\n\nOn-demand binary resolver (RIFT_BINARY_PATH -> PATH -> binaries/ -> version cache -> download) with SHA-256 sidecar verification, mirror (RIFT_DOWNLOAD_URL/RIFT_MIRROR_URL) and air-gap (RIFT_OFFLINE/RIFT_SKIP_BINARY_DO\n[…]\nupPath mock only matched 'rift', but on Windows the code\ntries 'rift.exe', 'rift-http-proxy.exe', etc. Updated the mock to match\nboth Unix and Windows binary names so the test passes on all platforms.",
          "is_bot": false,
          "headline": "feat(core): spawn transport rework + Mountebank-compat create() layer…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-10T00:31:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c317e78d436548c8315a31658720ec92140c305b",
          "body": "…connect(url) (#18)\n\nZero-dep fetch-based admin API client (rift.connect(url)) covering imposter, scenario-state, space, flow-state, and reload operations, with a typed RiftError hierarchy (InvalidDefinition/EngineUnavailable/CommunicationError/ImposterNotFound/EngineError) mapped from HTTP status and network failure. Supports await using via Symbol.asyncDispose plus close(). Unit-tested via mocked fetch; integration test self-skips without a rift binary.\n\nCloses #4",
          "is_bot": false,
          "headline": "feat(core): remote transport — admin HTTP client, typed errors, rift.…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-10T00:03:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "808207a2544e36f59c61f78f2374726bb9875a26",
          "body": "…cript/proxy builders (#17)\n\nChainable builders that produce the typed wire model: imposter()/onGet()/onPost()/on()/onAny()/stub(), response factories (ok/okJson/created/status/json/text/notFound/noContent), predicate helpers (equals/deepEquals/matches/contains/startsWith/endsWith/exists/and/or/not)\n[…]\nthe exact wire imposter; basic-api and error-testing fixtures are rebuilt byte-exact, the remaining fixtures documented as fromJson-only with accurate capability reasons. Zero runtime deps.\n\nCloses #3",
          "is_bot": false,
          "headline": "feat(core): fluent DSL — imposter/stub grammar, scenario FSM, fault/s…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-09T23:43:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f9e286d79778115a1d4319420e761bdfe040f98f",
          "body": "… fromJson escape hatch (#16)\n\nAdds a preservation-model wire layer: typed interfaces for the full Mountebank imposter/stub/predicate/response/behaviors grammar plus _rift extensions (exact camelCase wire keys), a fromJson escape hatch that validates structure and returns it verbatim (explicit ports\n[…]\n-safe serialization. Round-trips the rift example fixtures with value identity. Exposed under the wire.* namespace to avoid collisions with the legacy create()-era types. Zero runtime deps.\n\nCloses #2",
          "is_bot": false,
          "headline": "feat(core): typed wire model — Mountebank grammar + _rift extensions,…",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-09T23:20:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f64f114b7b495ca1eedf358072201c583fa774d5",
          "body": "…matrix, npm publishing (#15)\n\nHistory-preserving extraction of rift/packages/rift-node into this standalone repository.\n\nDelivers TypeScript/ESM build system, Node 20/22/24 x Linux/Darwin/Windows CI matrix, snapshot-based npm publish pipeline (dry-run on every push, snapshot dist-tag on master, stable publish gated on release), version target 0.12.1 with Node 20+ minEngineVersion, and CONTRIBUTING conventions doc.\n\nCloses #1",
          "is_bot": false,
          "headline": "build: repo bootstrap — extract packages/rift-node, TS/ESM build, CI …",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-09T23:01:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f4dbd6e041ebd0d18fa2b5c4e47e710346e7ae50",
          "body": "History-preserving extraction of rift/packages/rift-node into this repo. Adds Node 20/22/24 x linux/darwin/windows CI, a snapshot-based npm publish pipeline (dry-run on every push, snapshot dist-tag on master, stable publish gated on release), version target 0.12.1 with minEngineVersion, and a CONTRIBUTING conventions doc.\n\nCloses #1",
          "is_bot": false,
          "headline": "build: repo bootstrap — TS/ESM build, CI matrix, npm publish pipeline",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-09T22:58:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "966718a18c773d779e090a2848c674c110dcfc84",
          "body": "# Conflicts:\n#\tREADME.md",
          "is_bot": false,
          "headline": "Merge branch 'rift-node-extract' into build/rift-1-repo-bootstrap",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-09T22:40:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d6560cfffeee4593c5d5ba28856f315a409aaf08",
          "body": null,
          "is_bot": false,
          "headline": "docs: bootstrap README — SDK scope, planned API, artifacts",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-07-09T21:36:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0283c1a2a90669e82675b17d38ac4b05e6c91adb",
          "body": "* fix: use peek_response in get_rift_script_response to avoid double cycling\n\nThe get_rift_script_response function was incorrectly calling\nget_next_response() which advances the cycler. This caused response\ncycling to be off-by-one: the first request would return \"Response 2\"\ninstead of \"Response 1\n[…]\ns to use the sibling format that is compatible\nwith both Mountebank and Rift:\n\n  {\"jsonpath\": {\"selector\": \"$.name\"}, \"equals\": {\"body\": \"value\"}}\n\n* test: fix GET / test to check for _links structure",
          "is_bot": false,
          "headline": "docs: add practical examples and improve quickstart guide (#59) (#60)",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2026-01-02T19:32:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1afcbbc61999de5a4b2c1ebaeae1f1eb41034e32",
          "body": "Replace dual configuration approach (Mountebank JSON + native YAML) with\na single Mountebank-compatible JSON format that supports _rift namespace\nfor advanced features.\n\nThe _rift namespace allows advanced features (flow state, fault\ninjection,\nscripting) while maintaining full Mountebank compatibility.",
          "is_bot": false,
          "headline": "unify configuration to Mountebank format with _rift extensions",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2025-11-30T22:47:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5df9ec19d23964399f5b57fd78240519dcf5c5c3",
          "body": null,
          "is_bot": false,
          "headline": "rename npm package to @rift-vs/rift",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2025-11-28T15:43:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "41751748631d3d6827d1296b02b2b6cc11db63cb",
          "body": null,
          "is_bot": false,
          "headline": "add npm package with TypeScript bindings",
          "author_name": "Mohsen Zainalpour",
          "author_login": "EtaCassiopeia",
          "committed_at": "2025-11-15T10:08:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 1,
      "commits_last_year": 61,
      "latest_release_at": "2026-07-21T13:13:02Z",
      "latest_release_tag": "v0.15.0",
      "releases_from_tags": false,
      "days_since_last_push": 6,
      "active_weeks_last_year": 5,
      "days_since_latest_release": 8,
      "mean_days_between_releases": null
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@rift-vs/rift",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "mountebank",
            "mock",
            "stub",
            "test",
            "double",
            "chaos",
            "engineering",
            "rift",
            "service-virtualization",
            "api-mocking"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@rift-vs/rift",
          "is_deprecated": false,
          "latest_version": "0.15.0",
          "repository_url": "https://github.com/achird-labs/rift-node",
          "versions_count": 42,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 4813,
          "first_published_at": "2025-11-29T04:17:03.102000Z",
          "latest_published_at": "2026-07-21T13:13:26.876000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 8
        },
        {
          "name": "@rift-vs/rift-embedded",
          "exists": true,
          "license": "MIT",
          "keywords": [],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@rift-vs/rift-embedded",
          "is_deprecated": false,
          "latest_version": "0.15.0",
          "repository_url": "https://github.com/achird-labs/rift-node",
          "versions_count": 6,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 802,
          "first_published_at": "2026-07-19T00:49:39.030000Z",
          "latest_published_at": "2026-07-21T13:13:30.526000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 8
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 3
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "packages/rift-core/tsconfig.json",
        "packages/rift-embedded/tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 42365,
      "source_files_sampled": 117,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "koffi",
          "manifest": "packages/rift-embedded/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.9.0"
        }
      ],
      "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": 1,
        "merged_prs": 51,
        "open_issues": 2,
        "closed_ratio": 0.953,
        "closed_issues": 41,
        "closed_unmerged_prs": 1
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "EtaCassiopeia",
          "commits": 61,
          "avatar_url": "https://avatars.githubusercontent.com/u/209719?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "auto-release.yml",
        "ci.yml",
        "docs.yml",
        "engine-bump.yml",
        "publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        ".eslintrc.cjs"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "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": 10,
            "reason": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 1/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "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": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "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": 5,
            "reason": "dependency not pinned by hash detected -- score normalized to 5",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 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": "22 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "38680683f937f89e3dd6b23f4161e9f46cd9a756",
        "ran_at": "2026-07-29T23:00:09Z",
        "aggregate_score": 3.1,
        "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-29T08:31:07Z",
      "oldest_open_prs": [
        {
          "number": 95,
          "created_at": "2026-07-22T23:34:17Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-21T13:30:10Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 94,
          "created_at": "2026-07-21T16:31:53Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 96,
          "created_at": "2026-07-26T22:09:03Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/achird-labs/rift-node",
    "host": "github.com",
    "name": "rift-node",
    "owner": "achird-labs"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 57,
      "inputs": {
        "security": 31,
        "vitality": 67,
        "community": 40,
        "governance": 53,
        "engineering": 86
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 67,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 56,
            "inputs": {
              "commits_last_year": 61,
              "human_commit_share": 1,
              "days_since_last_push": 6,
              "active_weeks_last_year": 5
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 6 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "5/52 weeks with commits",
                "points": 3.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "61 commits in the last year",
                "points": 16.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 61
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "good",
            "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": 84,
            "inputs": {
              "releases_count": 1,
              "latest_release_tag": "v0.15.0",
              "releases_from_tags": false,
              "days_since_latest_release": 8,
              "mean_days_between_releases": null
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "1 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 8 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "cadence unknown (single release)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "release_cadence_unknown",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "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": 40,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "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": 18,
                "status": "met",
                "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": 62,
            "inputs": {
              "packages": [
                "@rift-vs/rift",
                "@rift-vs/rift-embedded"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 5615
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "5,615 downloads/month across npm",
                "points": 50,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 5615,
                      "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": 53,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "merged_prs": 51,
              "open_issues": 2,
              "closed_issues": 41,
              "issue_closed_ratio": 0.953,
              "closed_unmerged_prs": 1
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "95% of issues closed",
                "points": 44.6,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 95
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "51/52 decided PRs merged",
                "points": 37.5,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 51,
                      "decided": 52
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 1/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 39,
            "inputs": {
              "followers": 1,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "achird-labs",
              "public_repos": 8,
              "account_age_days": 11
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "1 followers of achird-labs",
                "points": 2.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 1,
                      "login": "achird-labs"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "8 public repos, account ~0 yr old",
                "points": 7,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 8
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@rift-vs/rift",
                "@rift-vs/rift-embedded"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 8
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "2 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 2,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 8 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "42 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 42
                    }
                  }
                ],
                "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": "excellent",
        "name": "Engineering Quality",
        "value": 86,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "5 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "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": ".eslintrc.cjs",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".eslintrc.cjs"
                    }
                  }
                ],
                "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": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": "https://achird-labs.github.io/rift-node/",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://achird-labs.github.io/rift-node/",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 31,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 31,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 3.1
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 1/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "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": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "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 5",
                "points": 2.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "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": "22 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 1
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 57,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.951,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "58 of 61 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 58,
                      "sampled": 61
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 59,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "packages/rift-core/tsconfig.json",
                "packages/rift-embedded/tsconfig.json"
              ],
              "agent_commit_share": 0,
              "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": ".eslintrc.cjs",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".eslintrc.cjs"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "packages/rift-core/tsconfig.json, packages/rift-embedded/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "packages/rift-core/tsconfig.json, packages/rift-embedded/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": "no agent-authored commits among the last 61",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 61
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "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 5",
                "points": 5,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 42365,
              "source_files_sampled": 117,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/117 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 117,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "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": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-29T23:00:28.792654Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/achird-labs/rift-node.svg",
  "full_name": "achird-labs/rift-node",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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