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

Infinibay / ken

ken context engine

PythonMIT★ 5 星标⑂ 1 复刻始于 2026年5月在 GitHub 上查看 ↗

Infinibay/ken 的健康指数为 100 分中的 48 分,处于「存在风险」区间。 其得分最高的类别是Vitality(71/100),最低的是Security(26/100)。 最近一次更新在今天。 近期的大部分工作由 1 位贡献者完成。

48
总分 / 100
存在风险

软件健康指数

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

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

评分画像

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

所有权

Infinibay组织
11 关注者15 个公开仓库始于 2022年10月

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

软件包生态系统

注册表软件包版本月下载量版本数最近发布
PyPIken-rank0.12.01,405180 天前

按类别列示的指标

活力

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

71良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 0 天前
6.2/36提交节奏 — 52 周中有 9 周有提交
17.4/18提交量 — 最近一年 86 次提交
0/10OpenSSF Scorecard:Maintained — project was created within the last 90 days. Please review its contents carefully
所用输入
commits_last_year86
human_commit_share1
days_since_last_push0
active_weeks_last_year9

发布纪律

88优秀
评分方式
16.2/27有发布版本 — 27 个版本标签(无 GitHub 发布版本)
36/36发布时效 — 最近一次发布版本于 0 天前
27/27发布节奏 — 约每 0.7 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count27
latest_release_tagv0.12.0
releases_from_tags
days_since_latest_release0
mean_days_between_releases0.7
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

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

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

社区健康

50中等
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
0/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template
评分方式
42/80月度下载量 — pypi 合计每月 1,405 次下载
0/20注册表被依赖数 — 该生态系统不报告此项
所用输入
packagesken-rank
dependents
ecosystemspypi
total_downloads
monthly_downloads1,405
已排除计分(无数据或不适用):注册表被依赖数。 其余权重已重新归一化。

可持续性与治理

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

37存在风险 · 占总体的 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
评分方式
0/46.8议题解决 — 没有议题或无数据
0/38.3PR 接受 — 没有已裁定的拉取请求或无数据
0/15OpenSSF Scorecard:Code-Review — Found 0/30 approved changesets -- score normalized to 0
所用输入
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
已排除计分(无数据或不适用):议题解决, PR 接受。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
7.8/25所有者影响力 — Infinibay 有 11 位关注者
16.4/25既往记录 — 15 个公开仓库,账户约 3 年
所用输入
followers11
owner_typeOrganization
is_verified
owner_loginInfinibay
public_repos15
account_age_days1,397
评分方式
25/25已发布且可解析 — pypi 上有 1 个软件包
35/35发布时效 — 最近一次发布于 0 天前
20/20版本历史 — 18 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagesken-rank
ecosystemspypi
any_deprecated
min_days_since_publish0

工程质量

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

66中等 · 占总体的 20%

工程实践

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

文档

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

安全

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

26危急 · 占总体的 16%

安全态势

26危急
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 无数据
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
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
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — 无数据
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 30 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate2.6
已排除计分(无数据或不适用):ci_tests, signed_releases。 其余权重已重新归一化。

AI 就绪度

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

45存在风险 · 占总体的 0%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
34.9/40可读的提交历史 — 87 次人类提交中有 57 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.655
agent_instruction_files
agent_instruction_max_bytes
评分方式
0/18一条命令的引导启动
22/22自动化测试
0/11Lint / 格式化配置
0/11静态类型检查
10/10可复现环境 — lockfile
10/10已体现的代理实践 — 最近 87 次提交中有 53 次由代理编写或署名代理
0/8自动化维护 — 未观察到自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfilesuv.lock
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configs
agent_commit_share0.609
toolchain_manifests
dependency_bot_commit_share0
评分方式
0/45可类型检查的代码 — Python,未配置类型检查
55/55可控的文件大小 — 采样的 146 个源文件中有 0 个超过 60KB
所用输入
primary_languagePython
largest_source_bytes59,965
source_files_sampled146
oversized_source_files0
评分方式
0/40API 模式(OpenAPI/GraphQL/proto)
20/20MCP 服务器
40/40可运行示例 — examples
所用输入
example_dirsexamples
has_mcp_signal
api_schema_files

关键数据

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

数据采集警告

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index pypi:ken-rank@0.12.0; advisories assessed against the repository dependency graph instead

更多细节

OpenSSF Scorecard 2.6 / 10
2.6综合

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
不适用CI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
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
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
不适用Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities30 existing vulnerabilities detected
直接依赖 13
注册表软件包版本约束清单文件
PyPItree-sitter>=0.25.2pyproject.toml
PyPItree-sitter-python>=0.23pyproject.toml
PyPItree-sitter-rust>=0.23pyproject.toml
PyPItree-sitter-javascript>=0.23pyproject.toml
PyPItree-sitter-typescript>=0.23pyproject.toml
PyPItree-sitter-go>=0.23pyproject.toml
PyPItree-sitter-java>=0.23pyproject.toml
PyPItree-sitter-language-pack>=1.8pyproject.toml
PyPIpathspec>=0.12pyproject.toml
PyPIwatchfiles>=0.22pyproject.toml
PyPIfastembed>=0.5pyproject.toml
PyPInumpy>=1.26pyproject.toml
PyPImcp>=2.0,<3pyproject.toml
全部依赖 未采集

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

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 24039,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Shell": 2907,
        "Python": 1245058
      },
      "pushed_at": "2026-07-30T20:06:44Z",
      "created_at": "2026-05-06T18:07:16Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-30T20:06:51Z",
      "description": "ken context engine",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": "https://www.infinibay.net",
      "name": "Infinibay",
      "type": "Organization",
      "login": "Infinibay",
      "company": null,
      "location": null,
      "followers": 11,
      "avatar_url": "https://avatars.githubusercontent.com/u/114872632?v=4",
      "created_at": "2022-10-02T16:15:46Z",
      "is_verified": null,
      "public_repos": 15,
      "account_age_days": 1397
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2026-07-30T20:06:26Z"
        },
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2026-07-29T23:54:42Z"
        },
        {
          "tag": "v0.10.2",
          "kind": "patch",
          "published_at": "2026-07-29T23:50:41Z"
        },
        {
          "tag": "v0.10.1",
          "kind": "patch",
          "published_at": "2026-07-29T23:25:39Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-07-29T23:11:27Z"
        },
        {
          "tag": "v0.9.1",
          "kind": "patch",
          "published_at": "2026-07-27T17:17:03Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2026-07-27T17:10:13Z"
        },
        {
          "tag": "v0.8.1",
          "kind": "patch",
          "published_at": "2026-07-27T13:34:27Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-07-27T03:31:32Z"
        },
        {
          "tag": "v0.7.1",
          "kind": "patch",
          "published_at": "2026-07-24T22:40:44Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-07-24T22:30:51Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-07-24T18:47:17Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-07-24T17:20:41Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-07-24T16:30:43Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-07-24T12:49:12Z"
        },
        {
          "tag": "v0.2.5",
          "kind": "patch",
          "published_at": "2026-07-23T17:52:31Z"
        },
        {
          "tag": "v0.2.4",
          "kind": "patch",
          "published_at": "2026-07-23T17:37:17Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-07-21T15:05:13Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-07-17T16:38:02Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-06-05T19:30:45Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-06-05T18:59:40Z"
        },
        {
          "tag": "v0.1.6",
          "kind": "patch",
          "published_at": "2026-06-05T16:51:58Z"
        },
        {
          "tag": "v0.1.5",
          "kind": "patch",
          "published_at": "2026-05-28T22:48:10Z"
        },
        {
          "tag": "v0.1.4",
          "kind": "patch",
          "published_at": "2026-05-22T14:20:39Z"
        },
        {
          "tag": "v0.1.3",
          "kind": "patch",
          "published_at": "2026-05-14T22:30:37Z"
        },
        {
          "tag": "v0.1.2",
          "kind": "patch",
          "published_at": "2026-05-14T20:32:43Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-05-14T20:26:57Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "80a32a0a445eac16fa2f6c80e655f35bf30f05a3",
          "body": "Replaces the MCP surface. Thirty tools cost ~2,700 tokens of schema before\nan agent had done anything, and a listing that long is itself a selection\nproblem: if a human engineer cannot say which of thirty tools answers a\nquestion, a model cannot either.\n\nThe split is deliberate, and it is not \"merge\n[…]\nctive channel\n    watched the agent work and scored none of it.\n\ntests: 691 passing, including a guard that no registered tool publishes an\nempty parameter schema — the class of bug, not the instance.",
          "is_bot": false,
          "headline": "Release 0.12.0: six tools instead of thirty",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-30T20:06:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "21bdfa87e19409567ca46474541d004638ec415e",
          "body": "The 0.10.2 patch release already shipped the guard and the schema fix\nto PyPI, but it deserved a minor bump rather than another patch:\n\n* Anyone still on 0.10.0 from PyPI needs a clear signal that the fix\n  is a non-patch change — the wheel had a wrong pin and a missed\n  migration, so silently re-releasing as a patch would understate it.\n* Adds a Troubleshooting MCP startup section to the README so users\n  who hit the same failure mode have something to land on when\n  searching.",
          "is_bot": false,
          "headline": "Release 0.11.0: minor bump for the MCP guard + README troubleshooting",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-29T23:54:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "945eba735b22e29ccb299cee397bead5684554fe",
          "body": "ken-rank 0.10.0 on PyPI shipped with the wrong pin (mcp>=1.0) and code\nthat only worked with that range. Installations done before the 0.10.1\nfix could resolve mcp 1.x and then fail at MCP server import with a raw\nImportError that the host assistant saw as 'MCP failed to start'.\n\n0.10.2 closes that \n[…]\nor every param.\n  ken tools file_symbols --no-include-docstrings used to fail because\n  argparse didn't see 'boolean' and rejected the --no- flag. The\n  schema now mirrors what the SDK itself derives.",
          "is_bot": false,
          "headline": "Release 0.10.2: guard the MCP startup against mcp<2.0",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-29T23:50:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ef55b29fa6c123866dfea95f2d4ac81a2f30b92a",
          "body": "- fix(mcp): migrate ken mcp server to mcp>=2.0 (c4954cf)\n- bump: 0.10.0 → 0.10.1\n\nThe MCP server in 0.10.0 imported from mcp.server.fastmcp, which\n2.0 removed; hosts pinned to mcp 2.x (opencode today) failed to\nregister any ken tools. 0.10.1 ports the server to mcp.server.MCPServer\nwithout changing the tool surface.",
          "is_bot": false,
          "headline": "Release 0.10.1: mcp 2.x compat",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-29T23:25:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4954cf47079dc0b7d4c4e59a02618b6b3cf9c82",
          "body": "mcp 2.0 removed the high-level FastMCP decorator surface\n(mcp.server.fastmcp). The ken MCP server was still importing\nfrom there, so 'ken mcp' crashed at startup with\nModuleNotFoundError, and opencode (and any host pinned to\nmcp 2.x) marked the server as failed and exposed zero tools.\n\nThe server no\n[…]\nsthrough) reads from a parallel registry\npopulated alongside the SDK registration so it doesn't have to\nspin up stdio to print --help.\n\nBumps mcp floor to >=2.0 in pyproject.toml; regenerates uv.lock.",
          "is_bot": false,
          "headline": "fix(mcp): migrate ken mcp server to mcp>=2.0",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-29T23:25:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ebfa700e781df09a836ce2c1b00c7fab6eef23cf",
          "body": "OpenCode (https://opencode.ai) has no lifecycle-hook equivalent to\nClaude Code or Codex CLI — its plugin system is JS/TS-based and runs\non Bun/Node. The documented way to expose structured tools to\nOpenCode is the MCP server block in opencode.json, which speaks the\nsame protocol ken already serves f\n[…]\npencode.py; existing\ntest_install_codex.py updated for the new install() signature.\n\nBumps to 0.10.0 — new feature (wiring a third assistant). Tagged\nv0.10.0 will trigger the publish-to-PyPI workflow.",
          "is_bot": false,
          "headline": "feat(install): wire ken into OpenCode via MCP",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-29T23:11:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e67c7449b0bf8c1510cc2559c3e9e97fd5f9d232",
          "body": "`tempfile.mkstemp` creates at 0600 for security and `os.replace` preserves that\nmode, so every `.ken/vectors/*.json` landed stricter than the `.vec` files next\nto it — 600 against 644 (or 664, depending on umask).\n\nHarmless when one user owns the tree. On a shared `.ken/` — CI, a container\nrunning a\n[…]\n back to the inline\ncolumn instead of reporting a permissions problem.\n\nSpotted in a user's `ls -l`, not by a test, which is why one now pins it.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(vectors): manifests inherit the umask, like the segments beside them",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-27T17:26:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "14203959b6294eb872619d98c674f57bdb83bcfc",
          "body": "0.9.0 moved the vectors out of `ken.db` and added a subcommand, and the README\nsaid nothing about either. Adds a section covering where they live now, the\nnumbers behind the move, and how to convert an existing project — including\nthat stopping the daemon first avoids its 5 s busy timeout, and that \n[…]\nin 219.2 s; it does not establish that `--embed` was\npassed, so the derived \"4 000 stored vectors a second\" claim is out until that\nis confirmed.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: document the vector store and `ken vectors migrate`",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-27T17:20:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1736a1e1df17a887a6f917451f9514b5a83a0183",
          "body": "`ken vectors migrate` set the `embedding` column to NULL and stopped. SQLite\nkeeps those pages on its free list, so the file did not shrink and the command\nprinted \"run VACUUM or `ken vectors compact` to reclaim disk\" — which was also\nwrong, since compact rebuilds the vector store and never touches \n[…]\n to render as \"0 MB\".\n\nVerified end to end on a simulated pre-0.9.0 index: 14.2 MB -> 0.5 MB, verify\nclean, second run reports \"nothing to move\".\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(vectors): migrate reclaims the freed pages (v0.9.1)",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-27T17:17:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "777c2b597eec58660f3212276c417169fd4782e9",
          "body": "Minor rather than patch: the on-disk layout changes. Vectors move out of the\n`embedding` columns into .ken/vectors/, the schema gains vec_slot plus the\nallocation, free-list and name-token tables, and `ken vectors` is a new\nsubcommand. Existing indexes keep answering correctly — every read path fall\n[…]\n— and `ken install` converts\nthem in place.\n\nOn a Linux 7.1-rc2 index: rank() 21.3 s -> 1.82 s, ken.db 4.10 GB -> 214 MB,\ntop-k output unchanged.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release 0.9.0: memory-mapped vector store",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-27T17:10:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c2a155f1fd889d5fe9cd394e4bac71252635e663",
          "body": "`ken rank` took 43.2 s on a Linux 7.1-rc2 index (101 083 files, 771 563\nsymbols) against a 60 s daemon timeout — and that was the floor, with no\nsession history for the reactive and predictive channels to score.\n\nProfiling put 97% of it in two channels, and cleared SQLite of blame. Over\nthe same 2.9\n[…]\nxisting indexes keep working untouched: every read path falls back to the\ninline column for rows without a slot, and `ken install` converts them.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(ranker): memory-map the vectors, invert the name tokens",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-27T16:49:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a24cbb4c65bb70a12b93615041a51c347f0fb230",
          "body": "….8.1)\n\n`ken install --embed` was 11.2s on a 753-file project and burned 400s of\nCPU doing it. Profiled: SQLite writes were 8%, the whole of I/O under\n10% — WAL with synchronous=NORMAL does not fsync per commit — while\nembedding was 60% and parsing 21%.\n\nThe embedding cost was not the model, it was \n[…]\ng a user can feel, and it\nwould slow the torch backend on many-core machines. OMP_NUM_THREADS\nremains available to anyone who wants the CPU back.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(indexer): batch the embedder across files, parse in parallel (v0…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-27T13:34:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "78ffa114fcbfbcda9606aae4d898f6cd83c79cfe",
          "body": "…6 languages (v0.8.0)\n\nThe static table becomes the default embedder for new projects and now\ntravels inside the wheel, so a fresh install has it offline with nothing\nto download.\n\nWhat changed about the table itself is what it was shown. v1 was fitted\non ~13 000 texts from a single workspace and wa\n[…]\nmports), registered for .html/.htm/.vue/.svelte, so\nthose files are indexed at all — they were the one gap in the languages\nthe table now covers.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(embedder): ship the static table in the wheel, balanced across 1…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-27T03:31:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "59af68afbb5184569966df30f06773fb256a89db",
          "body": "Adds a third backend: instead of running a network over every token, look\neach token's vector up in a fitted table, sum, project once per text,\nnormalise. Per token that is a gather and an add against 0.88 GFLOP for\nQwen3-Embedding-0.6B, and it needs neither torch nor ONNX — numpy and\ntokenizers, bo\n[…]\nefault, a\ndeveloper holding a cached table would otherwise run a different suite\nthan CI and learn about it through unrelated assertions failing.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(embedder): static token table as the default embedder when present",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-26T22:34:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d27b6ce0ac68a4bc26aa6cbbe5ea47b0d3b27100",
          "body": "sentence-transformers loads a checkpoint in its native dtype on an\naccelerator, so Qwen3-Embedding — ken's recommended model — runs in\nbfloat16 on CUDA. bf16's ~8-bit mantissa cannot represent a unit norm\nto better than a few parts in a thousand, and `_looks_encoded` demanded\n1e-3. Measured on an RT\n[…]\neturns norms within 1.2e-7 of 1.0, and its vectors agree with the\nCPU reference at cosine 0.999853 mean / 0.999639 min over 256 real\nindex texts.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(embedder): stop demoting healthy GPUs over bfloat16 rounding",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-26T21:49:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c3912988d90b7668bb018a8b6513c4c21acf51e7",
          "body": "0.7.0 shipped reporting `ken 0.6.0`. The version lived in two files —\n`pyproject.toml` for the package metadata and `src/ken/__init__.py` for\neverything at runtime — and only the first was bumped. It is not a one-off:\n0.5.0 went out the same way.\n\n`src/ken/__init__.py` is now the only place it is wr\n[…]\nto a clean venv: `ken --version`\nand `importlib.metadata.version(\"ken-rank\")` both report 0.7.1 — the check\nthat was missing when 0.7.0 went out.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release 0.7.1: make the version a single source of truth",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-24T22:40:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9c1a737a4e335ee1c7b7b86fb0ff018331081856",
          "body": "`_resolve_device()` only ever probed `torch.cuda`, so every Mac ran the\ntorch backend on the CPU no matter what. It now prefers CUDA, then MPS,\nthen CPU; `KEN_EMBED_DEVICE` gains `cuda` and `mps`, and naming one\naccelerator restricts the choice to it rather than substituting the other.\n\nMPS is trust\n[…]\nrdware: MPS correctness for this model is inferred\nfrom a shared root cause, not retested upstream. The guards are there\nbecause it could not be.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release 0.7.0: Apple Silicon (MPS) support for the torch embedder",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-24T22:30:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "67cdc3cb4be3fafabfe8147d7450d929eb7450ae",
          "body": "…ool catalogue\n\nThe old block spent ~780 tokens per prompt re-listing all 30 ken tools with a\none-line paraphrase each. The MCP handshake already puts every tool's name,\ndocstring and schema in the assistant's context (~3,250 tokens), so that was\nmostly duplication — and the tool docstrings are now \n[…]\n file\n  created moments ago is invisible to it. The fallback condition is now named\n  instead of left as \"when ken is insufficient\".\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: rewrite the recommended assistant prompt around policy, not a t…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-24T19:38:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "780cc924fe83899a4f8fc48e1c6af3681072e4bf",
          "body": "The pre-release review flagged test_search_symbols_leaves_prose_queries_on_pure_\nsimilarity as vacuous: its fixture held no symbol whose name overlapped the\nquery, so the literal channel could never have fired and the assertions held\nwhether or not `_identifier_query` rejected prose at all.\n\nRebuilt\n[…]\nion. Added a direct unit test of `_identifier_query` alongside it.\n\nTest-only; the shipped 0.6.0 behaviour is unchanged and correct.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "tests: make the prose-query gate test able to fail",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-24T18:55:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "134ad610cf90ba8bffbb9821bd4893917c7359a7",
          "body": "…ranker tools\n\nFollows the 0.3.0 ranker work by auditing every *other* tool for mathematical,\nstatistical and vector-space correctness, then putting the result through an\nadversarial review pass that found four more defects in the fixes themselves.\n\nEmbeddings — query/passage asymmetry:\n- Stored *do\n[…]\n\n\nAlso fixes `ken --version`, which reported 0.4.0 on a 0.5.0 install — the\n0.5.0 bump missed src/ken/__init__.py.\n\n555 tests (+36).\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release 0.6.0: fix the math, statistics and embedding use of the non-…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-24T18:47:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4237d6abd6ee4054c7e29c101d14f77168f613e0",
          "body": "Add two CLI commands for managing the embedding model:\n\n* `ken default-model [NAME]` — show/set/clear the default embedding model\n  for *new* projects, stored in the user config (~/.config/ken/config.json,\n  honoring KEN_CONFIG_DIR / XDG_CONFIG_HOME). Existing projects are never\n  touched; recommend\n[…]\nA new\nautouse conftest fixture isolates the user config per test so a real\n`ken default-model` override can't leak into the suite.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release 0.5.0: user-configurable default model + `ken models`",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-24T17:20:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a7e5591e4245a44ff7087c3a998c1d66bf05dd47",
          "body": "…king\n\nThe device only affects query embedding; the rest of a rank is CPU work\neither way. CPU is perfectly usable (incl. Qwen3); GPU mainly pays off for\nbulk reembed/indexing. Numbers from a real measurement.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: clarify CPU vs GPU embedding — little difference for inline ran…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-24T16:45:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2b6cf598e58ff4216fa80ba5fdf47f688882b2dd",
          "body": "… migration\n\n- New default embedding model: paraphrase-multilingual-MiniLM-L12-v2 (drop-in\n  384-dim; in the benchmark, +31% MRR and ~2x on non-English prompts vs the old\n  English-only all-MiniLM default, same footprint, faster).\n- GPU-aware fastembed backend: auto-detect CUDA/ROCm with CPU fallbac\n[…]\ns for device selection + model resolution; README section covering\n  reembed, the [gpu]/[torch] extras, and Qwen3 results + costs.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release 0.4.0: multilingual default, GPU-aware + torch embedder, safe…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-24T16:30:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7e7cf99703a9c4c578f61526c3b10ebc0e937185",
          "body": "Ships new context-rank capabilities, all flag-gated with the legacy\ndefault byte-identical to before (regression-verified), plus a new\n`ken reembed` command. Validated with a before/after harness over real\nsession history.\n\nRanker (opt-in via env flags):\n- Log-odds calibrated fusion (KEN_RANKER_FUSI\n[…]\ns library/pooling\n  changes a name/dim check misses).\n\ndocs/ranker-improvement-plan.md records the full plan and measured results.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add ranker improvements (opt-in) and `ken reembed`",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-07-24T12:49:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5a92c06178a9a7f437c6ca4f5ca7073bce5b9004",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 0.2.5",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-07-23T17:52:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ced8165e52d5451e19d51fe311202f4720a7f585",
          "body": "Pushing a v* tag now builds and publishes ken-rank to PyPI over OIDC,\nno stored token. One-time PyPI setup documented in RELEASING.md.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add GitHub Actions release workflow with PyPI Trusted Publishing",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-07-23T17:47:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "55306fb5a5bb381f904221ee573fd01edf818ae6",
          "body": "Rename distribution to ken-rank (the name 'ken' is taken on PyPI); the\nconsole command stays 'ken'. Restrict the sdist to source + metadata so\nit no longer bundles local caches.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release 0.2.4: publish to PyPI as ken-rank, trim sdist",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-07-23T17:37:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8341dfaee56f233bc03044f501701cd0e85f7417",
          "body": "…ools)\n\nReframe the CLAUDE.md/AGENTS.md Code Search guidance from capability-first\n(\"Use ken_X to…\") to question→tool (\"Which file implements X? → ken_search_files\"),\nmatching how an agent actually reasons — it has a question and needs to pick a\ntool. Also covers the four tools the prompt had been m\n[…]\n_forget) and corrects now-outdated\nPython-only labels on ken_callgraph/ken_type_hierarchy/ken_wiring (multi-language\nsince 0.2.0).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: make the recommended assistant prompt question-driven (all 30 t…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-21T16:01:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "61428c600ecd90048bea087d116e6f7bbbd200e0",
          "body": "Expose every tool the ken MCP server serves as a shell command, built\nlive from the same FastMCP registry so the CLI never drifts from the MCP\nsurface. Required params are positional, optionals are --flags derived\nfrom each tool's JSON schema, and every tool gets a real --help. Also\npropagate exit codes through `python -m ken`.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add `ken tools` CLI to run MCP tools from the shell; bump to 0.2.3",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-21T15:05:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "913ca01ae958515f0834974402a5ec0fa2202d73",
          "body": "…es; bump to 0.2.2\n\nGive cr_findings a deterministic relationship graph so saved knowledge stops\nbeing a flat list of isolated notes. Two additive tables:\n\n- cr_finding_refs — the finding→code bridge. Each finding's prose is resolved\n  (language-agnostically) against ci_files/ci_symbols on the durab\n[…]\nmalize; read tools degrade instead of raising; a dirty marker repairs refs\nafter a transient graph failure.\n\n466 tests pass (+27).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add findings knowledge graph: prose→code bridge + finding↔finding edg…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-07-17T16:38:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a6f9906dad55529dfae1a7c1007b59ffc7e5b8e0",
          "body": "Add `ken install --no-wire`: provision and index a project without wiring\nany assistant hooks / MCP config (.claude/.codex/.mcp.json), for hosts that\ndrive the daemon directly rather than via Claude Code / Codex.\n\nAdd three stateless read routes to the daemon, wrapping existing\nken.search / ken.grep\n[…]\nor a name\n\nThese back the Infinidev desktop app, which consumes ken as a context-rank\nsidecar. Also sync uv.lock to the declared 0.2.1 version.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: --no-wire install + daemon symbol routes for external hosts",
          "author_name": "Andrés Borek",
          "author_login": null,
          "committed_at": "2026-06-18T00:42:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "91c5267af6f0022c46afc3007b086e03814d7b28",
          "body": "…p to 0.2.1\n\nThree fixes from real-repo review feedback:\n\n- ken_architecture bounded its output by `limit`/`depth`: `layers` previously\n  dumped every node and `cycles` expanded each SCC fully, so a large monorepo\n  overflowed the token budget (187KB) regardless of args. Now cycles/clusters/\n  layer\n[…]\n paths, namespaces per-repo SHAs/state so nested\n  repos and duplicate SHAs don't collide, and tolerates unreadable dirs.\n\n439 tests pass (+3).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix architecture overflow, JS/TS env wiring, multi-repo cochange; bum…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-06-05T19:30:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5f8a29f46690c59b2140ef20a3789f150209af7b",
          "body": "…s; bump to 0.2.0\n\nCodeflow/import tools now work for any tree-sitter language, not just Python.\n\nImport resolution (src/ken/indexer.py, jsresolve.py, db.py, schema.sql):\n- Dispatch resolution by the importing file's language; add a `resolution`\n  column (internal/external/unresolved) with a guarded\n[…]\nonorepo: 166 previously-skipped\nfiles now indexed (~5.6k new symbols), internal import coverage 88.2%->89.0%,\nRust gaps 70->25. 436 tests pass.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Make ken language-agnostic: config-aware resolution + 10 new language…",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-06-05T18:59:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8b3ef039e4d2cbf4fdebbc5f8c1b9718c229e170",
          "body": "Ship 10 tools that answer \"how does X work?\" via local algorithms with\ncited, coverage-honest evidence — no LLM inference inside the tool:\n\n- ken_cochange      git-log association mining (support/confidence/lift +\n                    recency decay), subtracts the import graph for hidden coupling\n- k\n[…]\nstion is lazy (incremental via meta['cochange_last_sha']).\nREADME guidance block (for CLAUDE.md/AGENTS.md) documents all 10 tools.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add stochastic (non-LLM) code-understanding tools; bump to 0.1.6",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-06-05T16:51:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d46f32554ee894228847af8c1a6f7e0b7b14ffff",
          "body": "Drop a tree-sitter Dart parser and register the .dart extension. The\ngrammar ships in tree-sitter-language-pack (no standalone tree-sitter-dart\nwheel on PyPI), which pins tree-sitter>=0.25.2, so bump the core dep to\nmatch. Bump PARSER_VERSION to re-parse .dart files previously tracked as\nplain text.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add Dart support",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-31T01:09:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "60922c3ec850a97bb673f65bd15bdf434adc9310",
          "body": "SessionStart now auto-injects a \"where you left off\" brief so\ncontinuity and findings no longer depend on the model calling recall.\n/sessions/start returns a context_block built from the most-recent\nprompt across any session (last task, last turn narrative, touched\nfiles, recent findings); the hook prints it to stdout. Bump to 0.1.5.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Inject resume brief on session start",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-28T22:48:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "26b59ae8f488d3ab124123bca08da805c83c413c",
          "body": null,
          "is_bot": false,
          "headline": "Fix Claude session start hook matcher",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-23T22:53:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0156ec2d96c685c78c77c17ad553f16630874d2d",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.1.4",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-22T14:20:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b19b2e411f2c6da7ef28436ac87475162cd8c12a",
          "body": null,
          "is_bot": false,
          "headline": "Document ken MCP tool guidance",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-22T14:05:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "29d3a1f63c8fa77ca5e75f2b5a2e6adf26359ea4",
          "body": null,
          "is_bot": false,
          "headline": "Document install flow and add MIT license",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-22T13:59:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fbf0262a53117383128669a1d5263b2af1a33f2b",
          "body": null,
          "is_bot": false,
          "headline": "Improve recall relevance filtering",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-14T22:30:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cd393f9c99942644b4efb4dc4c341f3a74dce4a5",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.1.2",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-14T20:32:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fa10a844ebe1ebfd6bda24eb19d44758ea7014c",
          "body": null,
          "is_bot": false,
          "headline": "Add finding management tools",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-14T20:32:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "629791a7262d8b42f6f8cc5f4e02e5352819673e",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'main' of https://github.com/Infinibay/ken",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-14T20:26:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b00200922f417ec03671850375ec911244a44f63",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.1.1",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-14T20:25:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "45ec0a7e01b5096c859fc2a25f06e0c25e1f4ef6",
          "body": null,
          "is_bot": false,
          "headline": "Improve Ken reinstall and context output",
          "author_name": "Andres Jose Borek",
          "author_login": "anga",
          "committed_at": "2026-05-14T20:24:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "382590d825252c92abddcd5b0887668566dee310",
          "body": null,
          "is_bot": false,
          "headline": "Ranker: improve context precision signals",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-12T21:43:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d9f2724079f6c4b8a81340135447b29f693d54d",
          "body": null,
          "is_bot": false,
          "headline": "MCP: expose structured code context tools",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-08T13:39:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7d8a195a75fd02287fe526a9a2c9517b9806ea20",
          "body": null,
          "is_bot": false,
          "headline": "Fix recursive gitignore indexing",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-08T12:56:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f02fd7c7dccb67a695822cf30482a4d91897dd64",
          "body": null,
          "is_bot": false,
          "headline": "Install: refresh editable uv tool install",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T23:46:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5014f438cbde0cb5cf271c9f57d311a5f0db72cd",
          "body": null,
          "is_bot": false,
          "headline": "Fix manual rank query relevance",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T23:22:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79b6aabbb7147017c1a28b6e2cd1e06b6a514c36",
          "body": null,
          "is_bot": false,
          "headline": "Fix daemon startup on large repos",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T22:54:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e3780695112265bbd632719e2a61eadeacd97d99",
          "body": null,
          "is_bot": false,
          "headline": "Simplify injected context-rank format",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T22:07:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "593165793111702de792dee98fe438607b351d9f",
          "body": null,
          "is_bot": false,
          "headline": "Tests: verify doc-intent retrieval behavior",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T22:02:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c06b78e5d00bc381fc7e7a40cefbd4f104afea59",
          "body": null,
          "is_bot": false,
          "headline": "Add docstring intent ranking channel",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T21:57:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "69b5e7c7b1ce218bab81488d5e02acf7daf6acb3",
          "body": null,
          "is_bot": false,
          "headline": "Filter stale paths from search tools",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T21:35:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "624b9aa6dd5f0d3258097179a8aac6d19fbfcd0d",
          "body": null,
          "is_bot": false,
          "headline": "Filter stale paths from rank output",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T21:18:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f4823140af4be83179957613389334b53ed4b760",
          "body": null,
          "is_bot": false,
          "headline": "Report stale indexed files in status",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T21:14:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95ec1a93d19b26f3ac9b76835fad1ab2ef0a2347",
          "body": null,
          "is_bot": false,
          "headline": "Handle directory deletes in index queue",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T21:12:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0a3b18df3bb35d6741165ea1c9169e13a57be81",
          "body": null,
          "is_bot": false,
          "headline": "Finalize active sessions on daemon shutdown",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T21:08:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2f976c00510211f27b8d9743c1c8a02a42372343",
          "body": null,
          "is_bot": false,
          "headline": "Report partial embedding coverage in status",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T21:05:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fce358e51d74e1c8ed71f2b1240c58228598cf9d",
          "body": null,
          "is_bot": false,
          "headline": "Improve exact symbol ranking for large repos",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T21:03:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79ad1c82d3655883c430bdd3bc1f0e429e55e5cc",
          "body": null,
          "is_bot": false,
          "headline": "Add bounded eager embedding install mode",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T20:56:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25afc303846a23ad99660ef0b98a27b29d490ef9",
          "body": null,
          "is_bot": false,
          "headline": "Improve agent context ranking and install flows",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T20:53:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8644480b5a43aa808deefa694b4d31a60b44f1b4",
          "body": "`ken install` now also wires .codex/hooks.json (5 events: SessionStart,\nUserPromptSubmit, PreToolUse, PostToolUse, Stop) and registers the ken\nMCP server in .codex/config.toml. Stop hook handles Codex's\nlast_assistant_message field directly while still falling back to\nClaude Code's transcript_path. \n[…]\nll.\n\n12 new tests for the template (idempotent merge, user-entry\npreservation, MCP TOML block append/remove). Suite now 183 tests.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Codex CLI integration: install hooks + MCP alongside Claude Code",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T17:33:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "eddfc94cebd94cd2b5535cea878f68857cc4344b",
          "body": "Replaces the early-WIP stub with a real install/use guide. Adds the\nlitellm benchmark numbers (24-35% token cost reduction across read-only\nand write tasks) as concrete validation, plus a tour of what's inside\nand the legacy-rust tag pointer.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "README: install/usage guide + benchmark results",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T17:04:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f044fa7ad6a22f3481ec7ccfe5540d392bbad328",
          "body": "Adds 127 tests covering every testable code path outside the live HTTP\ndaemon, MCP server, and fastembed model load. Suite goes from 44 → 171\ntests in ~0.5s wall.\n\n- ranker: boosts (freshness/cooc/dismissal), fuzzy channel, output\n  rendering at all verbose levels, explain() per-channel breakdown,\n \n[…]\nith a deterministic FakeEmbedder.\n- daemon: DaemonState session bookkeeping, _extract_cited_paths,\n  IndexQueue dedup + lifecycle.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Tests: ranker boosts/fuzzy/output/explain/rank, parsers, daemon, indexer",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T15:22:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8316fb7c8dba18d8502b0f316de6a3a8d3d6abc9",
          "body": "Eleven correctness + consistency fixes across the rank pipeline. The\nbig ones:\n\n* Pattern multiplier was applied at both snapshot AND predictive,\n  inflating hot-pattern files exponentially across sessions. Snapshot\n  now stores the raw productivity score; predictive applies the\n  multiplier on cons\n[…]\nt_mentions (paths, bare names, qualnames, backticks), merge\n(synergy, alphabetical tiebreak), snapshot (raw storage, idempotency).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix ranker math: pattern double-amp, read_repeated, synergy, caps",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T02:33:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d50be65998e7c373995b43b4fd35440ebc05b688",
          "body": "Seven incremental signals + a debug surface for the context-rank\nranker, all sharing the same merge / boost pipeline as before:\n\n* PostToolUse failures retract the matching pre-phase interaction —\n  a broken Edit no longer counts as `edit:2.0`.\n* Fuzzy channel folds mtime recency into similarity *be\n[…]\nnst a different query.\n  ken_explain_rank(query) — per-channel breakdown + per-boost deltas.\n    For \"why didn't file X show up?\".\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Ranker round 2: explicit mentions, transcript citations, verbose levels",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T02:14:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0fadf1d601211109330ad94c2c0cfe697caf8e7c",
          "body": "Adds five tree-sitter extractors next to the existing Python one,\nsharing a small `_helpers.py` for sibling-walking, doc-comment\nstripping, and node text extraction. Each emits the same ParsedFile\nshape so the indexer doesn't grow language-specific branches.\n\n`_start_sibling()` walks through transpa\n[…]\nck_comment` accepts both `comment` and\n`block_comment` because tree-sitter-java names javadoc differently from\nthe JS/TS grammars.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Parsers: Rust, JavaScript, TypeScript, Go, Java",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T01:48:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "80a959b49a566039b2b1c695f98aa996d2a0a293",
          "body": "ken now exposes itself to Claude Code as an MCP server, registered\nautomatically via .mcp.json on `ken install`. Five tools that close\nthe gap between observational ranking (auto-injected on every\nprompt) and on-demand queries the model can call mid-conversation.\n\nSchema:\n- New `cr_findings` table (\n[…]\nng\n- remember/recall round-trip works (cosine on stored findings)\n- dismiss writes cr_interactions row with event_type='dismissed'\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 6: MCP server + 5 tools (search, recall, dismiss, remember)",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T01:39:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c046d0a9a906c1888647906120ef593a5070892a",
          "body": "The cr_interactions.context_id column was always there (schema v1)\nbut never populated. Wire it up: every tool-call interaction now\ncarries the id of the user_prompt context that anchors its turn.\nThe reactive channel uses that to apply per-turn decay on top of\nper-iteration decay — captures the use\n[…]\n1 (\"how does login work?\")\n  edit auth.py x3  → context_id=1\n  edit payments.py → context_id=6 (\"now fix charge() in payments.py\")\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Per-turn anchors + per-turn decay in reactive ranker",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T01:31:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "059bae8335a2d6eb4fe3401d4c0067f53cd7e440",
          "body": "Closes the loop. UserPromptSubmit now returns a ranked context block\nthat Claude Code prepends to the model's view, and SessionEnd snapshots\nthe session's productivity scores so future sessions have history.\n\nNew module ``ken.ranker``:\n- ``__init__.py`` — public ``rank(...)`` + ``RankedItem`` / ``Ra\n[…]\n its session_scores entry by 3.3×.\n\nThe system is now learning across sessions — exactly the loop the\nReadSkipped pattern unlocks.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 5: ranker (3 channels + 2 boosts) + <context-rank> injection",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T01:10:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "71588c196316498fab20e17bd3de07a96195516c",
          "body": "Adds the embedder module and threads it through the indexer + daemon.\nFiles, symbols, and user prompts now get 384-dim float32 vectors stored\nas BLOB in their respective tables — exactly what Phase 5's ranker\nwill consume.\n\nEmbedder (`ken.embedder`):\n- `OnnxEmbedder` wraps the Python `fastembed` pac\n[…]\nol vs 0.44 against `Session` and\n  0.31 against `expire` — the semantic signal the Phase 5 ranker will\n  consume is clearly there.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 4: ONNX embedder (fastembed) + integration",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T00:50:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "91b2e2aa05ef03c719d9ccba3b1013f343d30e99",
          "body": "Daemon now reacts to filesystem changes in real time. Adds and modifies\ntrigger a reparse (hash-skip absorbs no-op writes); deletes drop the\nfile from the index (CASCADE handles symbols / imports / refs).\n\nNew modules:\n\n- ``daemon/index_queue.py`` — thread-safe queue + worker. Coalesces\n  events by \n[…]\nlo/goodbye)\n- `rm src/added.py` → watcher fired → ci_files row deleted (CASCADE)\n- daemon /shutdown brings everything down cleanly\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 3: file watcher + incremental reindex",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T00:41:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5d7f1a28a4fce89f876e0a9a3476fd4d5a134e53",
          "body": "Replaces the Phase 1 stubs with a real per-project daemon. Hooks are now\nthin HTTP clients that spawn the daemon on first contact and silently\nfall back if it can't be reached (Claude Code never sees a hook fail).\n\nDaemon (`ken serve [PATH] [--background]`):\n- ThreadingHTTPServer on a free localhost\n[…]\noken → 401.\n- /shutdown brings the daemon down cleanly; runtime files are removed.\n- Cold hook after shutdown respawns the daemon.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 2: HTTP daemon + hook plumbing",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T00:24:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "45a5977e7474178e4ee32f019be72caae86b1948",
          "body": "Fresh start on the `rewrite` branch. New stack: Python 3.12 + uv + SQLite\n(per-project, in `.ken/`). Mirrors infinidev's context-rank shape but\ntalks to vanilla Claude Code via hooks instead of wrapping the agent.\n\nWhat works:\n- `ken install [PATH]` end-to-end. Creates `.ken/{ken.db,meta.json}`,\n  a\n[…]\nith\ncorrect symbols, qualnames, docstrings, and imports for a hand-rolled\nPython file. Re-running is idempotent (hash-based skip).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 1: Python rewrite skeleton + ken install",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-07T00:15:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3c4c18618a78f0e6429d73b42eb2e0b43b09fb55",
          "body": "Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Clean slate: wipe everything for rewrite",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T23:54:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "469f29b0658f10b987a03d1daf16b76251ad5397",
          "body": "- New `cuda` Cargo feature on engine + ken (off by default). When on,\n  pulls `ort` v2.0.0-rc.12 with the cuda feature and configures the\n  CUDA execution provider on FastEmbedder. ORT auto-falls back to CPU\n  at runtime if libcuda / libcudnn aren't loadable, so the same binary\n  works on both NVIDI\n[…]\nth\n  `KEN_BUILD_CUDA=0` to force CPU on a GPU host (portable artefact)\n  or `=1` to force CUDA on a CPU host (cross-compile prep).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Optional CUDA acceleration for the embedder + auto-detect in build.sh",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T23:10:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "60adfc360b457ee68513ef00f4fbcc120911f334",
          "body": "Reactive ranker:\n- New `Pattern::ReadSkipped` (multiplier 0.3×). Fires when a target was\n  Read 1–2× and never Edited, *while the same session edited a different\n  target*. Previously aliased into `Neutral` (1.0×) — files the agent\n  opened, evaluated, and walked away from were getting a positive bo\n[…]\nitch the leading-tag-name compare to `as_bytes()` slicing so\n  it's UTF-8-safe. Tag names are ASCII, so the byte compare is exact.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ReadSkipped pattern + HTML ingest panic on emoji-after-`<`",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T22:27:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3e15d961baae203d08b741c6d7dd3c44c3b585b6",
          "body": "Schema:\n- Migration 0005 drops vector(768) → vector(384). Existing embeddings are\n  NULLed; re-ingest required. Schema now matches AllMiniLML6V2Q.\n- Default model is mini-q (~3× smaller, ~5–10× faster than nomic-q on CPU).\n  Removed the 768-dim nomic options from the selector — only mini-q and\n  bge\n[…]\nn an empty Vec; ingest_uri detects\n  the length mismatch and fails the file as an adapter error so PG never\n  receives bogus rows.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Switch default embedder to mini-q (384d) + harden long ingests",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T22:06:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "295ec04fbaf5fc761fddf9ce3799a592ea732f22",
          "body": "* `FastEmbedder::from_env` reads `KEN_EMBEDDER_MODEL` to pick the model:\n  - nomic-q (default): NomicEmbedTextV15Q — quantized, 768d, ~2x faster\n    than full-precision nomic on CPU. Same embedding space, same vector(768)\n    schema, same asymmetric search_query/search_document prefixes — drop-in\n  \n[…]\nn 2x speedup with no DB migration. The 384d models give\na 5-10x speedup for fresh installs willing to accept lower-quality\nsearch.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Default to quantized NomicV15Q embedder (~2x faster on CPU, same schema)",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T19:31:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "be23637779fd3e822c515e3fbc49da3085dbd9b8",
          "body": "…URL on the CLI)\n\n* Add POST /ingest_codebase + POST /ingest_git server routes that accept a\n  workspace (id or name), an absolute path, and the same options the old\n  CLI took. Server does the heavy work using its own PostgresStorage +\n  embedder; returns flat stats JSON.\n* Refactor `run_ingest_cod\n[…]\n\nverified to keep working through the new `workspace` field shape.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Route all CLI ingest verbs through the HTTP server (no more DATABASE_…",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T19:08:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e9f39dcdeebd395cff81931c06c20fcfe719b2bf",
          "body": "…workspace by name\n\n* Add ContextKind::AssistantReply for the agent's final user-facing reply\n  (skips internal thinking / tool_use / tool_result blocks per the\n  user-facing-only intent).\n\n* Wire four new Claude Code hooks via `ken install`:\n  - SessionStart       -> rotate ken session_id, reset it\n[…]\nsts: 194 unit + 16 postgres integration (one new for anchor_turn).\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Session lifecycle hooks + dialog capture + per-turn anchor edges + --…",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T18:43:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "07d9d5fb9f4861a8a39720af0f614cf4c636cb98",
          "body": "Covers build, install via install.sh, running with `ken serve --with-pg`,\nwiring a project (workspace ids, ken install, initial ingest), and the\nMCP tools available inside Claude Code. Includes troubleshooting +\nre-indexing flows.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add top-level README with quick-start + 5-step setup guide",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T18:09:42Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "57ed6ccdf97238694e763997acd6ee81b0ce8fb5",
          "body": "* Project renamed: `cae-engine` -> `ken-engine`, server + cae-claude\n  collapsed into a single `ken` crate with one binary that takes\n  subcommands (`ken serve`, `ken ingest-*`, `ken mcp`, `ken install`,\n  `ken hook`). MCP server identifies as `ken`; state file is\n  `.claude/ken-state.json`; setting\n[…]\nser-only paths (no sudo).\n\nTests: 194 unit + 37 integration green.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Rename to `ken`, ship Phase 2 (MCP toolbelt + co-access edges)",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-06T18:04:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0848be7e34c41d3934dc38492ba5db099e0a848c",
          "body": "A Rust engine that pre-populates LLM context for coding agents.\nPostgres + pgvector index over code/docs with a multi-channel\nranker (semantic similarity, reactive session signal, predictive\nco-occurrence) and a Claude Code MCP integration.\n\nComponents:\n- crates/engine: storage, ingest pipeline, ran\n[…]\nMCP server + PostToolUse hooks for Claude\n  Code. Exposes query_context, search_symbols, list_files as\n  tools the agent can call.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Initial commit: context-ai-engine",
          "author_name": "Andres",
          "author_login": "anga",
          "committed_at": "2026-05-05T23:40:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 27,
      "commits_last_year": 86,
      "latest_release_at": "2026-07-30T20:06:26Z",
      "latest_release_tag": "v0.12.0",
      "releases_from_tags": true,
      "days_since_last_push": 0,
      "active_weeks_last_year": 9,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 0.7
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "ken-rank",
          "exists": true,
          "license": "MIT",
          "keywords": [],
          "ecosystem": "pypi",
          "matches_repo": null,
          "registry_url": "https://pypi.org/project/ken-rank/",
          "is_deprecated": false,
          "latest_version": "0.12.0",
          "repository_url": null,
          "versions_count": 18,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 1405,
          "first_published_at": "2026-07-23T17:30:24.759625Z",
          "latest_published_at": "2026-07-30T20:07:43.966514Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 5,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-05-22",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": null,
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 59965,
      "source_files_sampled": 146,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "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": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "tree-sitter",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.25.2"
        },
        {
          "name": "tree-sitter-python",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.23"
        },
        {
          "name": "tree-sitter-rust",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.23"
        },
        {
          "name": "tree-sitter-javascript",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.23"
        },
        {
          "name": "tree-sitter-typescript",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.23"
        },
        {
          "name": "tree-sitter-go",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.23"
        },
        {
          "name": "tree-sitter-java",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.23"
        },
        {
          "name": "tree-sitter-language-pack",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.8"
        },
        {
          "name": "pathspec",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.12"
        },
        {
          "name": "watchfiles",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.22"
        },
        {
          "name": "fastembed",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.5"
        },
        {
          "name": "numpy",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.26"
        },
        {
          "name": "mcp",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.0,<3"
        }
      ],
      "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": 0,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "anga",
          "commits": 86,
          "avatar_url": "https://avatars.githubusercontent.com/u/1065748?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "uv.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 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": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "30 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "80a32a0a445eac16fa2f6c80e655f35bf30f05a3",
        "ran_at": "2026-07-30T20:35:41Z",
        "aggregate_score": 2.6,
        "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-30T20:07:48Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": null,
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/Infinibay/ken",
    "host": "github.com",
    "name": "ken",
    "owner": "Infinibay"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 48,
      "inputs": {
        "security": 26,
        "vitality": 71,
        "community": 34,
        "governance": 37,
        "engineering": 66
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 71,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "commits_last_year": 86,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 9
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "9/52 weeks with commits",
                "points": 6.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 9
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "86 commits in the last year",
                "points": 17.4,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 86
                    }
                  }
                ],
                "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": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 88,
            "inputs": {
              "releases_count": 27,
              "latest_release_tag": "v0.12.0",
              "releases_from_tags": true,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 0.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "27 version tags (no GitHub releases)",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "version_tags_no_releases",
                    "params": {
                      "count": 27
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.7
                    }
                  }
                ],
                "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": 34,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "forks": 1,
              "stars": 5,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "5 stars",
                "points": 9.8,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 52,
            "inputs": {
              "packages": [
                "ken-rank"
              ],
              "dependents": null,
              "ecosystems": "pypi",
              "total_downloads": null,
              "monthly_downloads": 1405
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "1,405 downloads/month across pypi",
                "points": 42,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 1405,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "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": "at_risk",
        "name": "Sustainability & Governance",
        "value": 37,
        "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": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution",
                    "pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "no decided pull requests or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_decided_prs_or_data",
                    "params": {}
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "followers": 11,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "Infinibay",
              "public_repos": 15,
              "account_age_days": 1397
            },
            "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": "11 followers of Infinibay",
                "points": 7.8,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 11,
                      "login": "Infinibay"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "15 public repos, account ~3 yr old",
                "points": 16.4,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 15
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 3
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "ken-rank"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "18 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 18
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 66,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "1 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "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": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "critical",
        "name": "Security",
        "value": 26,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 26,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 2.6
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 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 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "30 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "at_risk",
        "name": "AI Readiness",
        "value": 45,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 35,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.655,
              "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": "57 of 87 human commits state their intent (structured subject or explanatory body)",
                "points": 34.9,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 57,
                      "sampled": 87
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 42,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "uv.lock"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.609,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "53 of the last 87 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 53,
                      "sampled": 87
                    }
                  }
                ],
                "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 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 59965,
              "source_files_sampled": 146,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/146 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 146,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "moderate",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": true,
              "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": 20,
                "status": "met",
                "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": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index pypi:ken-rank@0.12.0; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-30T20:35:48.211211Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/i/Infinibay/ken.svg",
  "full_name": "Infinibay/ken",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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