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

sarj-ai / standards

Cross-language lint rules for sarj-ai: ESLint plugin (TS) + Python AST checks (Python+SQL)

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

sarj-ai/standards 的健康指数为 100 分中的 44 分,处于「存在风险」区间。 其得分最高的类别是Engineering Quality(63/100),最低的是Community & Adoption(35/100)。 最近一次更新在今天。 近期的大部分工作由 1 位贡献者完成。

44
总分 / 100
存在风险

软件健康指数

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

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

评分画像

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

所有权

Sarj.ai组织
9 关注者1 个公开仓库始于 2023年10月

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

软件包生态系统

注册表软件包版本月下载量版本数最近发布
PyPIsarj-python-lint0.25.011,041300 天前

按类别列示的指标

活力

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

35存在风险 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 0 天前
2.8/36提交节奏 — 52 周中有 4 周有提交
17.9/18提交量 — 最近一年 97 次提交
0/10OpenSSF Scorecard:Maintained — project was created within the last 90 days. Please review its contents carefully
所用输入
commits_last_year97
human_commit_share1
days_since_last_push0
active_weeks_last_year4
评分方式
0/27有发布版本 — 未发布任何发布版本
0/36发布时效 — 没有发布版本
0/27发布节奏 — 没有发布版本
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count0
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

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

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

社区健康

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

可持续性与治理

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

46存在风险 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
0/22.5提交分布 — 头号贡献者编写了 100% 的提交
1.4/13.5贡献者广度 — 1 位贡献者
6/10OpenSSF Scorecard:Contributors — project has 2 contributing companies or organizations -- score normalized to 6
所用输入
bus_factor1
contributors_sampled1
top_contributor_share1
评分方式
0/46.8议题解决 — 没有议题或无数据
20.5/38.3PR 接受 — 已裁定的 PR 中 67/125 已合并
0/15OpenSSF Scorecard:Code-Review — Found 0/30 approved changesets -- score normalized to 0
所用输入
merged_prs67
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs58
已排除计分(无数据或不适用):议题解决。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
7.2/25所有者影响力 — sarj-ai 有 9 位关注者
7.7/25既往记录 — 1 个公开仓库,账户约 2 年
所用输入
followers9
owner_typeOrganization
is_verified
owner_loginsarj-ai
public_repos1
account_age_days1,014
评分方式
25/25已发布且可解析 — pypi 上有 1 个软件包
35/35发布时效 — 最近一次发布于 0 天前
20/20版本历史 — 30 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagessarj-python-lint
ecosystemspypi
any_deprecated
min_days_since_publish0

工程质量

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

63中等 · 占总体的 20%

工程实践

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

文档

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

安全

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

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

安全态势

37存在风险
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.2/2.5CI-Tests — 29 out of 30 merged PRs checked by a CI test -- score normalized to 9
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
1.5/2.5Contributors — project has 2 contributing companies or organizations -- score normalized to 6
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
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 — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — 无数据
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate3.7
已排除计分(无数据或不适用):signed_releases。 其余权重已重新归一化。

AI 就绪度

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

62中等 · 占总体的 0%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 100 次人类提交中有 99 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.99
agent_instruction_files
agent_instruction_max_bytes
评分方式
18/18一条命令的引导启动 — Makefile
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — packages/iac/pyrightconfig.json, packages/iac/src/sarj_iac_lint/py.typed, packages/lint-configs/pyrightconfig.json, packages/lint-configs/src/sarj_lint_configs/py.typed, packages/python/pyrightconfig.json, packages/python/src/sarj_python_lint/py.typed, packages/sql/pyrightconfig.json, packages/sql/src/sarj_sql_lint/py.typed, packages/typescript/tests/fixtures/tsconfig.json, packages/typescript/tsconfig.json
10/10可复现环境 — lockfile
10/10已体现的代理实践 — 最近 100 次提交中有 83 次由代理编写或署名代理
0/8自动化维护 — 未观察到自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfilespackage-lock.json, uv.lock
has_dockerfile
typed_language
bootstrap_filesMakefile
has_devcontainer
has_linter_config
typecheck_configspackages/iac/pyrightconfig.json, packages/iac/src/sarj_iac_lint/py.typed, packages/lint-configs/pyrightconfig.json, packages/lint-configs/src/sarj_lint_configs/py.typed, packages/python/pyrightconfig.json, packages/python/src/sarj_python_lint/py.typed, packages/sql/pyrightconfig.json, packages/sql/src/sarj_sql_lint/py.typed, packages/typescript/tests/fixtures/tsconfig.json, packages/typescript/tsconfig.json
agent_commit_share0.83
toolchain_manifests
dependency_bot_commit_share0
评分方式
27/45可类型检查的代码 — Python,已配置类型检查(packages/iac/pyrightconfig.json, packages/iac/src/sarj_iac_lint/py.typed, packages/lint-configs/pyrightconfig.json, packages/lint-configs/src/sarj_lint_configs/py.typed, packages/python/pyrightconfig.json, packages/python/src/sarj_python_lint/py.typed, packages/sql/pyrightconfig.json, packages/sql/src/sarj_sql_lint/py.typed, packages/typescript/tests/fixtures/tsconfig.json, packages/typescript/tsconfig.json)
55/55可控的文件大小 — 采样的 303 个源文件中有 0 个超过 60KB
所用输入
primary_languagePython
largest_source_bytes54,324
source_files_sampled303
oversized_source_files0

关键数据

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

数据采集警告

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index pypi:sarj-python-lint@0.25.0; advisories assessed against the repository dependency graph instead

更多细节

OpenSSF Scorecard 3.7 / 10
3.7综合

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
9CI-Tests29 out of 30 merged PRs checked by a CI test -- score normalized to 9
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
6Contributorsproject has 2 contributing companies or organizations -- score normalized to 6
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
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
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
不适用Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
全部依赖 未采集

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

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 1984,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Python": 2415795,
        "Makefile": 3728,
        "JavaScript": 20884,
        "TypeScript": 889441
      },
      "pushed_at": "2026-07-27T17:26:43Z",
      "created_at": "2026-05-20T17:18:18Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-27T17:27:42Z",
      "description": "Cross-language lint rules for sarj-ai: ESLint plugin (TS) + Python AST checks (Python+SQL)",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python",
        "TypeScript"
      ]
    },
    "owner": {
      "blog": "https://www.sarj.ai/",
      "name": "Sarj.ai",
      "type": "Organization",
      "login": "sarj-ai",
      "company": null,
      "location": "Saudi Arabia",
      "followers": 9,
      "avatar_url": "https://avatars.githubusercontent.com/u/148175495?v=4",
      "created_at": "2023-10-17T02:54:34Z",
      "is_verified": null,
      "public_repos": 1,
      "account_age_days": 1014
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [],
      "recent_commits": [
        {
          "oid": "2900c402d5edd6ec9481b5af2ef3233ec75a6283",
          "body": null,
          "is_bot": false,
          "headline": "Release non-nullable collection rules (#125)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-27T17:26:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "18f082a7bd1e83ce672bcb704f38a3ba3044800c",
          "body": null,
          "is_bot": false,
          "headline": "Add non-nullable collection rules (#123)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-27T15:43:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "431a19b88ad3bbab07d8be6c64ce762ad0b4557f",
          "body": "…oss-package convergences (#120)\n\n* Add 14 mock-quality and expressiveness rules (SARJ048-063)\n\nWhere the SARJ040-047 family asks \"does this test assert anything?\", this wave\nasks \"does it exercise anything real?\" — it pushes suites off hand-rolled\ndoubles and onto the real store, the real database,\n[…]\nmarks the success arm of a `match` whose `case _`\nraises. The pattern is the assertion there. SARJ057's docstring claims zero false\npositives, but its corpus did not include `faris`. Fixed separately.",
          "is_bot": false,
          "headline": "Mock-quality rules (SARJ058-071), a TypeScript port rule, and four cr…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-27T14:29:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7ff78e5052b5399840aae6201e00839cbcd14134",
          "body": "SARJ057 reports `faris/python/falltime/falltime/tests/services/test_pdf_processor.py:96`\nand `:112`:\n\n    match PROCESSOR.process(source_file=protected, password=\"not right\"):\n        case PDFProcessError(error=DecryptionError.INCORRECT_PASSWORD):\n            assert True\n        case _:\n            \n[…]\nA\n`match` with no failing arm proves nothing and still fires, and the exemption\nreaches the arms rather than the enclosing function, so a constant assertion\nafter the `match` still fires. Both pinned.",
          "is_bot": false,
          "headline": "Exempt a `match` arm marker from SARJ057 (#124)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-27T14:29:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a98d88932d6e628abe506048bc555c71e9224e84",
          "body": "* Tighten SARJ049/051/052/053 from a 26k-file external audit\n\nThe five rules shipped to bulbul in #4147 were measured at zero over 883\nfiles and landed blocking. The zero reproduces (889 files at the merge\ncommit, canary-verified), but zero on a repo whose comments SARJ016 has\nalready scrubbed says \n[…]\nuuidv7 fixture\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0163gKKSD9MBEACoXo773b2b\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Tighten SARJ049/051/052/053 from a 26k-file external audit (#122)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-27T12:17:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3b69a955edbbc759500f39e2d824b7b56c200905",
          "body": "…ord (#121)\n\n* docs(lint): retire SARJ055 — corpus says filler-adverb is convention, not slop\n\nRecords SARJ055 no-filler-success-adverb on the never-reuse roster so the code\nis not recycled and the rule is not rebuilt from the same premise.\n\nIt was fully implemented and corpus-validated before being\n[…]\nhanged.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0163gKKSD9MBEACoXo773b2b\n\n---------\n\nCo-authored-by: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add SARJ056 no-optional-tenant-predicate, and correct the SARJ055 rec…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-27T12:17:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c7eddbf990d65780bb615a1b44fa88f0cc672e4c",
          "body": "…atchet) (#118)\n\nPorts the custom lint logic bulbul hand-rolls in its own\n`.pre-commit-config.yaml` and `python/scripts/` into the shared standards\npackages, so consumers get it from the repo that owns it.\n\nThree new Python rules (sarj-python-lint 0.21.0):\n  SARJ052 no-stdlib-logging\n  SARJ053 no-ge\n[…]\ned with\nSARJ054; behaviour is unchanged (79 existing tests still pass).\n\n\nClaude-Session: https://claude.ai/code/session_0163gKKSD9MBEACoXo773b2b\n\nCo-authored-by: Claude Opus 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Move bulbul's custom lint out of bulbul (SARJ052-054, SARJ109, sarj-r…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-27T00:17:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "21aae7fd540def3efb1d894193d47befa2023267",
          "body": "From a 37,918-comment, nine-repo measurement study. Two live SARJ016 false\npositives are fixed, five detectors are added to it, and three new deletion-class\nrules ship with a Python/TypeScript twin each.\n\nSARJ016 false positives, both reproduced by running the shipped rule:\n\n  * the region check mat\n[…]\n decision on whether\n\"extract a named boolean\" grazes the complexity veto) and the PR-diff comment\nbudget (a CI script, not a rule).\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Ship the anti-comment-verbosity rule family (SARJ049-051) (#117)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T19:54:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c396c216fbf428569b553d1e06ef9b3279f4c137",
          "body": "Investigation: no SARJ rule flagged private access. Three checkers did, and\nnone distinguishes first-party from third-party:\n\n* ruff PLC2701 import-private-name — exempts \"same top-level package\", not\n  \"ours\". 74 sites over bulbul's five packages; 3 are livekit-agents internals\n  private since 1.6.\n[…]\non: attribute access needs receiver types\nthat no AST rule has. Both configs document that limitation and its per-line\nescape hatch.\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Exempt third-party privates from the private-import check (#116)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T19:29:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "adc477d8bbb13bf0cbbfd8f9afc76f459f5e234c",
          "body": null,
          "is_bot": false,
          "headline": "Update standards dependencies (#115)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T15:39:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "de0b490a7a8e038f09e64a5582a51f258d48318c",
          "body": null,
          "is_bot": false,
          "headline": "Harden TypeScript rules from five-repo audit (#114)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T15:17:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f42bcc47990b29452fce086a97c44e982fe96c45",
          "body": null,
          "is_bot": false,
          "headline": "Harden rules from bulbul PR 4111 findings (#113)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T14:44:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f315dcdb7430ad6babb7b9d6b0b1cbad3e3ebd57",
          "body": null,
          "is_bot": false,
          "headline": "Expand corpus hardening and speed up rules (#112)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T14:10:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "00b4d05911753280563ba01653727faac6cf3bd0",
          "body": null,
          "is_bot": false,
          "headline": "Harden custom lint rules (#111)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T13:04:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aa626353a81fb2816945aa73748d1b687ea205a1",
          "body": "…(#110)\n\nSeven rules fire on code carrying a `DO NOT EDIT` header, where their advice\ncannot be acted on: the layout is the generator's, and re-running it discards\nany edit. Found while measuring what bumping bulbul's repo-wide pin from 0.12.2\nto 0.17.0 would cost — the answer was +2 findings, both \n[…]\nader spellings are\nexempt, and the identical body without a header still fires.\n\n4155 tests pass, ruff clean, basedpyright 0 errors.\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(python-lint): never flag generated files in style rules (0.18.0) …",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T12:00:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8cb1e708214d2b524e1a96972cfc93b4e79604d8",
          "body": "….0, ts 2.11.0) (#109)\n\n* fix(lint): 10-agent FP audit over 4,877 files of popular OSS (py 0.17.0, ts 2.11.0)\n\nRan every rule in both plugins against real third-party code and fixed the\nfalse positives at the rule, never at the call site.\n\nCorpora: 2,657 Python files (fastapi, pydantic, black, sqlmo\n[…]\nipt 1332 tests pass, typecheck clean, build succeeds.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(lint): 10-agent FP audit over 4,877 files of popular OSS (py 0.17…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T11:46:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "04166dfedf44a31808da54b556f25107747e1b4f",
          "body": "…eep (0.16.0) (#108)\n\nRan all 39 Python rules over 798 files of third-party code (pydantic, flask,\nhttpx, requests, rich) — code that shares none of our idioms, which is the only\nway to see the false positives our own repos cannot reveal. Four FP classes\nfound, all fixed at the rule rather than supp\n[…]\nrowed to `>>>` only, with a regression test pinning the banner behaviour.\n\n3792 tests pass (+49), ruff clean, basedpyright 0 errors.\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(python-lint): eliminate false positives found in a third-party sw…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T01:58:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9a1dc142b50364e990390dd9d24c5d04b9adf840",
          "body": "…2.11.0, lint-configs 0.7.2) (#103)\n\nRebased onto main, which has moved a long way since this branch was cut: #105\nwired 12 previously-unreachable rules into `eslint.strict.mjs` and added a\ntier-parity guard, and #107 landed at ts 2.10.0 / lint-configs 0.7.1. Versions\nrenumbered accordingly (2.10.0 \n[…]\nreviewed decision rather than a\ndefault.\n\n1195 tests pass.\n\n\nClaude-Session: https://claude.ai/code/session_016H4qAQpU9Bn52WNK6a5iPM\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(lint): strict means error — promote every warn-tier severity (ts …",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T01:39:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "65bb95b8ee21878ba38b12bb713fdc3c0447cba4",
          "body": "…II arm, export specifiers, the missing narration shape (ts 2.10.0, py 0.15.1) (#107)\n\n* fix(python-lint): secret-name predicate was blind to leading boolean flags (0.15.1)\n\n`no-secret-in-log` (SARJ012) fired on `has_secret`, `hasSecret`, `is_token` and\n`isToken`. Every one is a false positive: a bo\n[…]\nrict`, all checked on every test run. So the label is\nremoved rather than updated again, and the comment points at the tests instead.\n\nNo rule or severity changes; the wired ruleset is byte-identical.",
          "is_bot": false,
          "headline": "fix(lint): close the disclosed gaps — twin secret-name FP, raw-body P…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T01:28:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5ca40366dbf58c77e50da7aeabb3b3d67b6906b7",
          "body": "… reached no consumer) (#105)\n\n* fix(lint-configs): wire the 12 rules from 2.8.0/2.9.0 into the strict config\n\n`@sarj/eslint-plugin` registers 41 rules; `eslint.strict.mjs` referenced 30.\nEvery rule added by #101 and #102 was missing, and the header comment still said\n\"Full @sarj/eslint-plugin@2.7.0\n[…]\nis a minor, not a\npatch. uv.lock regenerated with `uv lock`.\n\n1104 tests pass, typecheck clean, lint-configs suite green.\n\n---------\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(lint-configs): wire 12 shipped rules into the strict config (they…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T01:12:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "21d859f56869ce048576d6f588f2975e2fb0715b",
          "body": "…0 (#106)\n\n#104 bumped the root pyproject.toml to 0.15.0 but not\npackages/python/pyproject.toml. release.yml's `detect` job watches the\npackage manifest, so it saw no version change, skipped publish-python, and\n0.15.0 never reached PyPI or got a python-v0.15.0 tag. The release run\nreported success b\n[…]\n. That\nis why the mismatch merged green.\n\nConsumers pinning ==0.15.0 (noura-be's test-quality hook) are broken until\nthis publishes.\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(python-lint): publish 0.15.0 — package manifest was left at 0.14.…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T01:06:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8608d9ca3d513c5bf7fd776f5b6011374ef576d2",
          "body": "…(0.15.0) (#104)\n\nAdds SARJ040-047, the first substantial batch of test-scoped rules since\nSARJ031. Mined from an AST audit of ~7,500 test functions across 601 files\nin bulbul and noura-be.\n\nThe audit dropped far more than it kept. Confirmed absent from both corpora:\nxunit setUp/tearDown, mutable mo\n[…]\nipe.\n\nRebased onto #102, which took SARJ038/SARJ039 and 0.14.0; renumbered from\n038-045 to 040-047 and bumped to 0.15.0 accordingly.\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(python-lint): 8 test-quality rules mined from a 7.5k-test audit …",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T00:42:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "976e10da2544da527c6eb54f89b64e29a472ca06",
          "body": "… follow-ups (#102)\n\n* feat(typescript-lint): no-zod-native-enum — ban z.nativeEnum (2.8.0)\n\nSchema-layer sibling of no-enum (SARJ-928). Flags `z.nativeEnum(...)` and\n`z.enum(SomeTsEnum)`; autofixes inline string-literal object arguments to\n`z.enum([...])`. Registered in index.ts, warn in recommende\n[…]\nndings against\nthis repo's own `python/`, `sql/` and `iac/` sources.\n\n3436 tests pass, ruff clean, basedpyright 0 errors.\n\n---------\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(lint): rules mined from 2 years of PR review — TS + the 3 Python…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-26T00:28:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "aa6cd498d91b7f8d7728b02dfcdd9632fef0d4d8",
          "body": "…to ESLint, Python parity, FP pass (#101)\n\n* fix(typescript-lint): kill 6 adoption false positives + 2 calibration blockers (2.5.0)\n\nFirst at-scale adoption (42k-LOC Cloudflare Workers codebase) produced a triaged\nFP list with reproductions. Each is fixed with the repro text pinned as a `valid`\nregr\n[…]\nnt-promise-catch.test.ts`; 1048 -> 1021 tests, all green.\n\nVersion: 2.7.0 collided with main's release, so this is 2.8.0.\n\n---------\n\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(typescript-lint): 29 -> 39 rules (2.8.0) — Biome plugins ported …",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-25T23:48:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d7dec9d32ee4a64079c7b1cd0802392f3f802709",
          "body": "…dit (2.7.0, lint-configs 0.6.1) (#100)\n\n* feat(typescript-lint): 4 rules mined from PR review + 5-repo smell audit (2.7.0)\n\nNew rules, all syntactic (no type services), from 2 years of PR review\nfeedback plus a 5-repo TS code-smell audit. Corpus-validated against\ndashboard-fe, bulbul (app + precede\n[…]\nget repo its 2,566 findings are unactionable; revisit only if an\ni18n layer lands. Plugin stays 2.7.0 (unpublished). 748 tests green.\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(typescript-lint): 4 rules mined from PR review + 5-repo smell au…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-25T15:54:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "742fe2f02a6f8e3feb536f02e0e894b8aca63b3e",
          "body": "…1) (#99)\n\n* feat(python-lint): 5 rules mined from 2y of PR review feedback (py 0.13.0)\n\nAdds SARJ032-036, each mined from recurring review feedback / code-smell\naudits, each validated against the four production corpora (bulbul, noura-be,\nai, bell) with per-hit TP/FP sampling before landing:\n\n- SAR\n[…]\n(50-70% on famous+internal corpora); the code number is burned per\nthe 004/005 precedent — dropped-before-release codes stay retired.\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(python-lint): 5 rules mined from 2y of PR review feedback (0.13.…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-25T15:43:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a48822447cc5368c9c193a8ffae291d2a39083e7",
          "body": "… 2.6.0) (#98)\n\nStrengthens both linters' no-comment-cruft to catch the two highest-volume,\nlowest-FP classes of superfluous AI-generated comments, in Python and TypeScript:\n\n- Step narration: 'First, ...' / 'Then, ...' / 'Finally, ...' / 'Step 2:' — a\n  comment that walks through the code line-by-l\n[…]\n3) are genuine hedges / step markers at a low\nper-file rate. PY 2891 tests, TS 668 tests, ruff + basedpyright + tsc + build clean.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(lint): no-comment-cruft flags redundant narration (py 0.12.2, ts…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T14:46:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "422fe58ca497867e1a0da47ddd22787b73cab923",
          "body": "Flags the two type-safety escape hatches: `x as any` / `<any>x`, and the\n`x as unknown as T` double-cast. Exempts `as const`. Two message ids so the\nhalves can be tiered independently.\n\nValidation (before/after across bulbul, noura, Angular, Grafana, Zod, cal.com,\nVue): the DOUBLE-CAST detection is \n[…]\nmended and strict; consumers can disable the asAny\nmessage id if they already run no-explicit-any. tsc clean, 660 tests, build ok.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(typescript-lint): add no-unsafe-cast rule at warn (2.5.0) (#97)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T14:41:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6210d953e70b7413f8a7bc98ce7956315ff0578e",
          "body": "…ep (0.12.1) (#95)\n\nValidated each fix against bulbul + Home Assistant / SQLAlchemy / scikit-learn /\npoetry / rich with real before/after hit counts. bulbul is unchanged by every\nfix (0 regressions on our own code); reductions are on the famous corpora.\n\n- no-sentinel-return-on-except: broaden the O\n[…]\nnly caller'; report the true\n  reference line. SQLAlchemy 270->252, sklearn 449->437.\n\n2882 tests pass, ruff + basedpyright clean.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(python-lint): FP-correctness pass on 5 rules from famous-repo swe…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T13:39:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1ba85c41a79d0f35e7bf38e8b23dfad1da513b93",
          "body": "… sweep (2.4.1) (#96)\n\nValidated each fix against bulbul + noura + Angular / Grafana / cal.com / Vue\nwith real before/after hit counts. bulbul unchanged by every fix.\n\n- enforce-file-structure: gate the use-server check on an actual misplaced\n  use-server directive, not any /actions/ path segment (w\n[…]\n accumulators, and more ordered\n  iterable names (buffer/stream/teleport/chunk/queue/drain).\n\ntsc clean, 660 tests pass, build ok.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(typescript-lint): FP-correctness pass on 5 rules from famous-repo…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T13:38:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "400709b58c54d3e12f7c784b14c89a1892303154",
          "body": "…s on store modules\n\nBoth rules' messages say 'Store query ...' but, unlike their siblings\n(no-select-star / store-insert-requires-on-conflict / no-aggregation-in-store-query),\nthey lacked the is_store_module() path gate — so they fired on docstring SQL\nexamples and SQL-generation libraries (e.g. SQ\n[…]\n Assistant in the corpus sweep); store\nfiles still fire.\n\nNo version bump — batches with the other FP fixes into the next release.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(python-lint): gate no-offset-pagination + no-query-with-many-join…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T12:50:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2fdf9b02c25d927abd8b13181c496c4fe334044e",
          "body": "…d config\n\nFollow-up to sarj-lint-configs 0.5.0, which enforced docstring content/\nformatting (D205/D400/D401/D413/DOC201/DOC402), exception-message style\n(TRY003/EM10x), RUF067, TC004, and pyright reportUnknown*/reportAny at error.\nThis cleans the three lint packages' own code to satisfy them:\n\n- R\n[…]\nTID251).\n\nBehavior unchanged — rule test suites stay green (python 2806, sql 103,\niac 39); ruff + basedpyright clean on all three.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(lint): make python/sql/iac own code pass the newly-strict share…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T03:35:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3a828cc9c2a723d79c6f5cb77af2425871075e53",
          "body": "Incorporate bulbul's stricter/extra settings back into the shared\nsarj-lint-configs strict config so every repo gets bulbul-equivalent\nultra-strict linting by importing the standard (not by re-implementing):\n\n- eslint.strict.mjs: add perfectionist (sort-objects/interfaces/classes/\n  jsx-props/union-\n[…]\nllow-up: packages/python, sql, iac own code has pre-existing findings under\nthe newly-enforced rules — cleanup tracked separately.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(lint-configs): make strict config the canonical superset (0.5.0)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T01:07:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f1ccf291f3dd5cee68a5df531cc14f7fb0079d28",
          "body": "* chore(deps): bump all dependencies to latest\n\n- packages/sql: transitive minors (diff-cover 10.4, platformdirs 4.11,\n  regex 2026.7.19, tqdm 4.69); sqlfluff already at latest 4.2.2\n- packages/{python,iac,lint-configs}: uv lock --upgrade found everything\n  already at latest (pytest 9.1.1, ruff 0.15\n[…]\ntional _walk parity\n  import (reportPrivateUsage)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(deps): bump all dependencies to latest (#94)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T00:27:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "699ca528eb2ffaf758765e3f838e356c50612d2e",
          "body": "…p (2.4.0)\n\nValidated all rules against VS Code, the TypeScript compiler, NestJS, Next.js\nand Excalidraw; fixed the false-positive patterns real code exposed. Each fix\nships regression tests from the actual FP site.\n\n- enforce-file-structure: classify exports by what they introduce, not the\n  export\n[…]\n by type (Checkbox/RadioGroup/Slider); skip hidden.\n- prefer-schema-for-api-payload: recognize hand-written type-guard validation.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(typescript-lint): FP-correctness pass from 5-repo validation swee…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T00:18:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a2994260f3ffc8ac7b799bfd43740787e0ce8137",
          "body": "…p (0.12.0)\n\nValidated all rules against Flask, requests, FastAPI, httpx, Django, pydantic\nand fixed the false-positive patterns found in real code. Each fix ships\nregression tests built from the actual FP site.\n\n- inefficient-string-concat-in-loop: stop flagging .join()/str()/os.path.join\n  reassig\n[…]\nre.py / stores/ path.\n- no-comment-cruft: suppress code-shaped illustrations in prose/doc comments\n  and pseudo-code placeholders.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(python-lint): FP-correctness pass from 6-codebase validation swee…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-23T00:02:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b3c75dddb496ee7df42f030c822a90dff5036df5",
          "body": "…ly-owned operands\n\nAdd a type-provenance guard to the comparison-cluster shape: don't flag when\nthe operand's value provably originates from a type we don't own — a property\nof a .d.ts/node_modules type (DOM getComputedStyle().overflowY, an API field\nfrom another package), the return of such a meth\n[…]\nlable fix for these. On bulbul this class\nwas ~11 of 18 remaining warnings. Second-fastest rule; short-circuits without\ntype info.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(typescript-lint): prefer-string-literal-union — suppress external…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T23:05:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "46d8e8620854e7f6c4d2037ceed82719fd6f262e",
          "body": "The comparison-cluster shape fired on any ref compared against 2+ string\nliterals, including refs already typed as a named string-literal union\n(CallStatus, discriminated-union tags) — a syntactic rule can't see through\na named/imported union. On bulbul that was 131/133 false positives.\n\nNow gate th\n[…]\normation; the choice-field shape stays syntactic. Adds the plugin's first\ntyped RuleTester harness (tests/fixtures/tsconfig.json).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(typescript-lint): make prefer-string-literal-union type-aware",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T21:30:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "75de0921e2668886b4eb6f79f4c8aaf057975fca",
          "body": "no-secret-in-log: expand INNOCUOUS_WORDS descriptor nouns + require raw\nsecret value (not derived/redacted) for secret-named object properties.\nno-fat-try-blocks: allowlist non-throwing web-platform constructors\n(TextEncoder/Blob/ReadableStream/Response/...) so single-await handlers\nthat build strea\n[…]\nal unions.\nno-cors-wildcard-with-credentials, single-public-export: no rule change;\nadded adversarial valid regression cases only.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(typescript-lint): FP-hardening pass on 5 ported rules",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T12:15:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "11e7f8f3cbe65d123034eb1aa674f4ffc6707afa",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(typescript-lint): remove no-template-literal-in-log rule",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T11:02:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "cf4611a90cc07d67aa39160aafd1c9d84a466cf2",
          "body": "…S2367)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(typescript-lint): drop unreachable PrivateIdentifier guard (tsc T…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T10:51:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ff9c4fc11798dcf9a2eb34ff38d3e7d9e5472126",
          "body": "Ports (corpus-validated FP~0 on demo-gateway/sarj-demos/bulbul/noura):\n- no-fat-try-blocks, no-cors-wildcard-with-credentials, no-template-literal-in-log,\n  no-secret-in-log, single-public-export, prefer-string-literal-union.\nwarn in recommended; error in strict (prefer-string-literal-union stays warn — high volume).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(typescript-lint): 2.3.0 — 6 rules ported from sarj-python-lint",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T10:49:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "27f9d2d546a0fc25a60fd059a8e850617462b158",
          "body": "Removes len-as-truthiness (SARJ027), no-manual-log-prefix (SARJ029), and\njson-response-not-parsed (SARJ030) — high-volume report-only rules the team\nopted not to keep. Retains SARJ025 no-offset-pagination, SARJ026\nprefer-namedtuple-over-tuple-return, SARJ028 no-cors-wildcard-with-credentials,\nSARJ031 no-sleep-in-test-body. 26 rules; suite 2743 passed.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release(python-lint): 0.11.1 — drop SARJ027/029/030 (too noisy)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T10:10:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4f60ab1612f9b8e358486a56f6816c875113cd1a",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release(python-lint): 0.11.0 — 7 new rules SARJ025-031",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T02:29:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2238ba0e4516270cd83586d1711fb257ec38f916",
          "body": "…+ cutting-edge practices\n\n- SARJ025 no-offset-pagination — OFFSET-token pagination in Python-embedded SQL → keyset cursor\n- SARJ026 prefer-namedtuple-over-tuple-return — public fn returning bare heterogeneous tuple[...]\n- SARJ027 len-as-truthiness — len(x)==0/>0/... → not x / x (zero-boundary only)\n[…]\n asyncio/time.sleep() directly in a test_* body\n\nAll ~0% FP on bulbul+noura, ruff-uncovered. +333 tests (suite 2901). Registry +7.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(python-lint): 7 new rules (SARJ025-031) mined from audit skills …",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T02:29:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "36005385eab2f72aac8a4bb8ab82335914b04d18",
          "body": "no-repeated-string-literal now fires only when a structured literal repeats\n3+ times (still across >=2 distinct functions), reducing noise on 2-use pairs.\n_MIN_OCCURRENCES 2->3; docstring + tests updated.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release(python-lint): 0.10.1 — SARJ024 requires >=3 usages (was 2)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-22T01:39:59Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d76350e505b291bdc141efd2b4666e4d1b16e079",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release(python-lint): 0.10.0 — rule hardening, FP elimination, perf",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T22:32:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "07ebf4ecf597a734809559b9f43792f65cadeb45",
          "body": "feat(python-lint): 0.10.0 — rule hardening, FP elimination on bulbul+noura, perf",
          "is_bot": false,
          "headline": "Merge pull request #93 from sarj-ai/lint/single-public-export",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T22:18:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "18cd08166ce062144f84060443f653591a201a92",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "style(python-lint): ruff format the fix-wave sources",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:46:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "727c97440ec40db988a0aa8d199d5b54fa89761b",
          "body": "- FN: add snake_case get_logger to the logger-factory set so\n  structlog.get_logger().info(f\"...\") is caught alongside stdlib getLogger.\n- FN: walk the +-concat BinOp tree of the first positional arg so an\n  interpolating f-string wrapped in a BinOp (f\"{x}\" + \"!\") is flagged, while\n  interpolation-f\n[…]\nthree strict-xfail markers now that the behaviour is correct.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 81aa550f585117e644d28a8d11fe736e6159c415)",
          "is_bot": false,
          "headline": "fix(SARJ017): close no-fstring-in-log FN/FP gaps",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d1a9e388f97a7b539429ff1c8cc4e03e7b1fa0fb",
          "body": "Add a shared _sql.strip_sql_noise() helper that masks the contents of\nsingle/double-quoted SQL string literals and the bodies of -- / block\ncomments in a single length-preserving pass before any keyword or comment\nscan. All four SQL-aware store rules now run their keyword/comment/backtick\ndetection \n[…]\nlse\npositive correctly dropped) shows no new false positives.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 8aa9f518f421a75c42950f13b9b4ca7946e012ad)",
          "is_bot": false,
          "headline": "fix(sql-lint): SQL string-literal awareness across SARJ018-021",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "04b7d9d7b0853b90e0435bad098fba27227b7068",
          "body": "… refs\n\nFixes four stepdown defects flagged by the adversarial-edge-case wave:\n\n- Comprehension targets are a separate py3 scope; `_locally_bound_names`\n  no longer treats a `for _x in ...` target Store as shadowing the helper.\n- Bound-name shadowing is now per-caller (subtracted from that function'\n[…]\n old global-shadow logic missed),\n0 removed, noura unchanged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 209067b3d87fc47949268368d401e6cc6b11f4cf)",
          "is_bot": false,
          "headline": "fix(SARJ023): scope shadowing per-function, track class-name & lambda…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4ee1d0f59bd6062e8a0a434872a2187dae705f07",
          "body": "…mption\n\nno-fat-try-blocks had two defects encoded as strict xfail tests:\n\n- _can_raise walked nested def/async def/lambda bodies via ast.walk,\n  counting calls that never execute at try-time. Now walk only the same\n  executable scope (skip nested-scope bodies; keep decorators/defaults).\n- _all_hand\n[…]\nlaced with a\n  path-exit analysis: exempt iff every handler raises on all paths.\n\nRemoves the 5 xfail markers those tests carried.\n\n(cherry picked from commit df97cc64df455090e45dcd659aba14208774ff8c)",
          "is_bot": false,
          "headline": "fix(sarj007): scope-aware raise-counting and generalized re-raise exe…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8d6cf868debec4ad86bfc6e11b34f6deae3a106c",
          "body": "SARJ012 (no-secret-in-log):\n- `tag` redaction marker is now a WHOLE-TOKEN match, not a substring, so\n  `staging_secret` / `staging_token` (which contain \"s·tag·ing\") are no longer\n  silently exempted — that was a secret leak.\n- add plural `secrets` / `passwords` to the secret-word set (were asymmetr\n[…]\nion,\nwhich is fragile and risks masking real secret compares.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 3b67c95d111190c40dd58dcd1864c6c4dacc13c6)",
          "is_bot": false,
          "headline": "fix(SARJ011/SARJ012): close real secret-name defects in shared predicate",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "afcfff7ebb4592a3e603ef1ee3d47c5d17401903",
          "body": "…nction threshold\n\nA literal appearing once at module level and once inside a single function\ncounted as two distinct scopes and fired, violating the rule's contract of\n\">=2 distinct enclosing functions/methods\". Count only real function scopes\n(drop the module sentinel) before applying the distinct\n[…]\ngatives for bare GROUP BY / ORDER BY single-clause fragments.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 1a085e64d155d82bc6892ac2a248c49a4a343f81)",
          "is_bot": false,
          "headline": "fix(python-lint): SARJ024 module scope must not count toward cross-fu…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3bb8ba87c1ea2c8c148bb9d00a8d3ae1fade41de",
          "body": "…on-except\n\nFix three defects in the logged-sentinel exemption:\n\n- Receiver-name check was substring `\"log\" in name` — wrongly exempted\n  non-loggers `dialog`/`catalog`/`backlog`. Now token/suffix-based: the name\n  is or ends (on an underscore/start boundary) with log/logger/logging.\n- Call-receiver\n[…]\nit.\n\nFlip the three strict-xfail regression tests to passing.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 04db9c5818d5c7e32a18f57eaae6ee059408e2d1)",
          "is_bot": false,
          "headline": "fix(sarj009): harden logged-sentinel exemption in no-sentinel-return-…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d067985031a041eb5040b15631ddf55994145206",
          "body": "…` annotations\n\nTwo clean prefer-str-enum defects fixed:\n\n- FN: `match subject: case \"a\": case \"b\":` string patterns were invisible to\n  the comparison-cluster detector (they are not `Compare` nodes). A match on a\n  name/attribute subject now feeds its `MatchValue` / `MatchOr` string-literal\n  case \n[…]\n (e.g. env \"dev\"/\"prod\" mapped to an Enum), 0 removed, 0 FPs.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit bbeb590b7295f6802b81dc6de53850f59738ab98)",
          "is_bot": false,
          "headline": "fix(SARJ006): detect match/case closed sets + resolve stringized `str…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3959cbb21c75b77088dd22f7dfa163ea73c98db6",
          "body": "…orward-ref FNs + fixture FP\n\nUnwrap Annotated[T, ...] to its first type arg before the dict[str, Any]\ncheck; strip string forward-refs before eval-parsing so leading whitespace\nno longer raises SyntaxError; resolve string constants in the dict VALUE\nposition; skip @pytest.fixture functions (not a p\n[…]\nct).\nFlips the four strict-xfail regression tests to passing.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit ea673d43d9f7ac22ca99410fe3726013a3f6107d)",
          "is_bot": false,
          "headline": "fix(lint): close SARJ008 pydantic-at-boundaries defects — Annotated/f…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "05df1e4e20b4769e42bd9a0703bec51814709737",
          "body": "… no-sequential-await\n\nTwo genuine false positives in the gather-antipattern detector:\n\n- `_is_gather_antipattern` used `ast.walk`, descending into a nested\n  `async def`/`lambda`. A loop-var await living in that nested scope pushed\n  the loop, so a genuinely loop-invariant `await` at body level got\n[…]\nata-flow tracking whose clean form risks new false positives.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit af0bf6067488e429a0d289bafcbf335099ab2d75)",
          "is_bot": false,
          "headline": "fix(SARJ001): clear nested-scope + async-generator false positives in…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "aea96c26cf681575b0eeb43d2aade986c851e27a",
          "body": "…refer-class-row\n\n`row_factory=(rf := dict_row)` binds and passes dict_row at runtime, but\n_factory_name only handled Name/Attribute, so the walrus-wrapped case was a\nfalse negative. Unwrap ast.NamedExpr to its .value before the name check.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit b788fde9d451096bfa0e3a6ad5245b5316bb5a33)",
          "is_bot": false,
          "headline": "fix(SARJ013): unwrap walrus (NamedExpr) around row_factory value in p…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "99919fefd64622bb58e9a62b0f82e52eea9a2f07",
          "body": "…walrus RHS; stop leaking loop depth into nested defs\n\n- _looks_like_string now recognises IfExp ternaries, %-format Mod BinOps, and\n  walrus NamedExpr wrappers as string-ish RHS forms.\n- Loop detection covers AsyncFor.\n- Plain self-referential reassignment (s = s + x) is flagged like s += x.\n- Rese\n[…]\n the six xfail markers now that the behaviour is implemented.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 194791b18f38a82670e3f3ebbbd050070d30cc38)",
          "is_bot": false,
          "headline": "fix(SARJ002): detect async-for, plain reassignment, ternary/%-format/…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6958ba3b04fd65c16bb94ca98cfcf2af18c247f1",
          "body": "…mment-cruft\n\n_is_directive matched via bare startswith, so commented-out code whose first\ntoken merely starts with a directive word (todos, noqant, hackers) was silently\nsuppressed. Require the keyword to be a whole token: when a directive prefix ends\nin a word char, the following char must be a wo\n[…]\ncts; corpus scan (bulbul + noura, 1922 files) byte-identical.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 3a2c7792e5028036b253e3327919437a513d5fa1)",
          "is_bot": false,
          "headline": "fix(SARJ016): require word boundary after directive keywords in no-co…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "853b7e02e19651896f47ca7b561cd69200fe968c",
          "body": "… in prefer-timedelta\n\nTwo false positives in the BaseSettings exemption of prefer-timedelta-for-durations:\n\n- Name-collision: `_resolve_settings_classes` keyed classes by bare name, so a\n  nested class reusing a real BaseSettings class's name shadowed it in the index\n  and leaked the real settings \n[…]\nct=True) regression tests to passing and removes the markers.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 3e261925d5d67eb7fdce75337ff292aa451ff753)",
          "is_bot": false,
          "headline": "fix(SARJ014): clear name-collision + subscripted-base false positives…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f1d66823a651e7cdcc3ad710399b5c9fbeaf50e6",
          "body": "…unk-drawer stem gate\n\nAdd GraphQL->graphql and gRPC->grpc to _ACRONYM_OVERRIDES so their\nsnake_case renders as a single token. Lower-case path.stem before the\njunk-drawer denylist check so capitalized stems (Utils.py) are gated.\nFlip the three xfail-pinned regression tests to passing.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 3db0d20016479bbb681e10749524b441246a95e1)",
          "is_bot": false,
          "headline": "fix(SARJ022): acronym overrides for GraphQL/gRPC + case-insensitive j…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8125cc4ded391ab0197f8949d920667e9904c851",
          "body": "The generator-marker exemption in no-unreachable-after-terminal had two\ndefects:\n\n- FN: an exempt `yield` right after a terminal caused a whole-list `break`,\n  swallowing a genuinely-dead non-yield statement after the yield. Scan\n  per-statement now: skip markers, flag the first real dead statement.\n[…]\n the two strict-xfail regression pins encoding this behavior.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit ad0cdcbf92c498fca0f5a691109d6e44d330fd97)",
          "is_bot": false,
          "headline": "fix(SARJ010): per-statement yield exemption + assigned-yield markers",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T20:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "705585ac9bb9b4f679d3bee6761ddb8c2ee86cca",
          "body": "… xfail-pinned defects\n\nOne adversarial agent per rule hunting FP/FN beyond the first hardening wave.\nValidated all 6 perf optimizations as behavior-correct (SARJ003 _ast_equal +\nSARJ023 inlined-walker node-multiset parity). New strict xfails pin real defects\nacross 20 rules (SARJ003/015 clean); rec\n[…]\nring-literal awareness, substring matches (tag/log receiver).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 23b56e883ee0b6c8f6e71168a0cdf6b5a3354ad6)",
          "is_bot": false,
          "headline": "test(python-lint): adversarial edge-case wave — +314 regressions, +62…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:34:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "661aff8f8fce594d32afb7833372e1485e0b4c9e",
          "body": "…o-secret-in-log\n\nExtend the shared is_secret_name innocuous-token denylist with boolean\npresence/state/discriminator markers (present, set, unset, configured,\nmissing, required, valid, invalid, exists, type, types) so identifiers\nlike token_present, password_set, password_configured, and credential\n[…]\nen, api_key, password, auth_token,\nclient_secret) still fire.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit d63dff512121e05342e1607cde1fab1a81527884)",
          "is_bot": false,
          "headline": "fix(SARJ012): clear boolean-flag / redaction-tag false positives in n…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:22:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9675113191d9e83e2fb1dfd4deea31f7600b6147",
          "body": "… check\n\nComparing a secret-named operand to a compile-time str/bytes literal is a\nsentinel/placeholder/state check (e.g. `password == \"PLACEHOLDER\"`), not a\ntiming-attack surface — an attacker cannot extract a runtime secret by timing\na compare against a fixed literal (hardcoded-secret literals are\n[…]\nme-operand compares (`cached_hash != token_hash`) still fire.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 04b9d5f1aa2cddf7b33faf3c93a500e8612b99dc)",
          "is_bot": false,
          "headline": "fix(SARJ011): exempt secret-vs-literal comparisons from constant-time…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:22:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "55076e6adfb33aa0a21f8b57a2d61e9ac2d9ce88",
          "body": "…query\n\nAnalytics/reporting queries against the columnar BigQuery mirror legitimately\naggregate (COUNT/GROUP BY/DISTINCT is their whole job); the rule targets OLTP\nPostgres store queries, so flagging them is a scope mismatch. Mirror the existing\nClickHouse exemption exactly: exempt files importing t\n[…]\ne OLTP-store\naggregation with no BigQuery signal still fires.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit e6aee6b61a782887b1ab27f6dc02b1d3f91b5ad1)",
          "is_bot": false,
          "headline": "fix(SARJ020): exempt BigQuery analytics from no-aggregation-in-store-…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:22:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1c42dc2c2984ff8068082f21fe505c4605d440bb",
          "body": "no-aggregation-in-store-query parsed and walked every file's full AST\neven when no SQL was present, and re-walked every string literal's\nsubtree to mark it consumed. Add a file-level early exit (a diagnostic\nneeds both a query verb and an aggregation keyword; source is a superset\nof every literal, s\n[…]\nmean on the bulbul python\ntree (same-machine controlled run).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit b4154b42f78467d2cbafc2261504982147266a48)",
          "is_bot": false,
          "headline": "perf(SARJ020): file-level gate + skip redundant per-Constant AST walk",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:10:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d2502dc4cfa5690cb40d9b7c539c8d0cec7c585e",
          "body": "Replace per-arm ast.dump() same-target comparison with a recursive\nstructural comparator (_ast_equal) that is exactly equivalent to\nast.dump(a)==ast.dump(b) but allocates no strings, and merge the two\nfull tree walks (elif collection + main scan) into one BFS pass.\n\nBehavior identical: 2035 passed / 19 xfailed unchanged, hits 27/run.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 0c67b2a148938e335eb46a3ac7c2c7132bbc5455)",
          "is_bot": false,
          "headline": "perf(python-lint): speed up SARJ003 no-isinstance-union-chain ~2.4x",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:10:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "db73c9e10af941f0ec108a4efd939ea440ddf480",
          "body": "SARJ006 walked the AST ~3 times per file: ast.walk for class fields,\nast.walk to find functions, plus per-function _walk_own_scope passes.\nCollapse into a single DFS that tracks the enclosing-function cluster\nmap (None at module level / inside nested class or lambda bodies,\nmatching the old scope bo\n[…]\nr (1685 -> 1399 us/file under load; ~821 -> ~682 normalized).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 6a8311658f1a60792429b8745b821fd1a0e868a7)",
          "is_bot": false,
          "headline": "perf(prefer-str-enum): fold three tree walks into one DFS",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:10:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "713ec79a35a3fe6f8d2e7961947c2a186ed28027",
          "body": "Collapse the two ast.walk passes (_collections_bindings + check) into one\nlinear traversal that collects import bindings, import-from findings, and\nnamedtuple call candidates together, then post-filters calls by the complete\nbindings set. Preserves exact BFS emission order and all diagnostics.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 8a3663bca7bc0b081c2071c91a2ecea9468d1590)",
          "is_bot": false,
          "headline": "perf(python-lint): single-pass SARJ015 (prefer-struct-over-namedtuple)",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:10:11Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6d60fb23a52ad4ab68223bd24202a7b4fe91585b",
          "body": "no-repeated-string-literal walked the AST five times per file (four\nast.walk passes for f-string/docstring/scaffolding exclusions plus a\nrecursive scope map, then a final ast.walk to collect candidates).\nCollapse all of it into one DFS that registers each exclusion at the\nancestor node before descen\n[…]\nessages are unchanged; the 2035-test suite is byte-identical.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 4998ccea5cb08b5a3da2d0448f44fae998006f2f)",
          "is_bot": false,
          "headline": "perf(SARJ024): fold 5 tree traversals into a single DFS",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:10:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fbcdeca0afb741da72d1e7472cdb124c684d2262",
          "body": "The SARJ023 stepdown rule ran ~9 full AST traversals per file with\ndifferent node-filter semantics, dominated by the stdlib ast.walk ->\niter_child_nodes -> iter_fields chain (a generator layer plus a\ngetattr-per-field tuple allocation on every node).\n\nIntroduce _child_nodes / _walk: a single iterati\n[…]\n15x faster over the corpus (1860 -> 1617 us/file, best-of-5).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit c4a45b35ae5f7b8faddd2508cce86d778934b6b2)",
          "is_bot": false,
          "headline": "perf(stepdown): replace ast.walk with an inlined child-iterator walker",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T18:10:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a072cf38b043baa8a25ca4a0df45e90df5f722ba",
          "body": "Replace naive substring matching in no-secret-in-log (SARJ012) and\nprefer-constant-time-secret-compare (SARJ011) with a shared\n`is_secret_name` predicate in `_secret_names.py`.\n\nThe predicate splits identifiers into snake_case / camelCase tokens and\nmatches a secret word only as a WHOLE token, then \n[…]\n fixture equality assertions are\nnot a timing-attack surface.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 5c422b2f3c803034abc38ee747237ad5df06a052)",
          "is_bot": false,
          "headline": "fix(lint): whole-token secret matching for SARJ011/SARJ012",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:53:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "184841c0fed77be8bddb5a5dcfb7afcc0ec1bb34",
          "body": "Fields on a BaseSettings-derived class are populated from environment\nvariables, whose bare-numeric wire values timedelta cannot parse. Exempt\nAnnAssign fields on any class deriving from a ...Settings base — directly\nor transitively through an intermediate module base. Ordinary BaseModel\ndomain fields stay flagged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 5346baea5d87472acdc635e0a6eb8c4e3eba82fe)",
          "is_bot": false,
          "headline": "fix(SARJ014): exempt pydantic-settings fields from prefer-timedelta",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:53:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5da90ad82a79a8e7e5c6bdce27331bc8bfd411b6",
          "body": "Add a logged-sentinel exemption: an `except` handler that logs the\nexception (`logger.*`/`log.*`/`logging.*` at a standard level, on a\nreceiver whose name contains \"log\") before returning the sentinel is\nobservable, not a silent swallow, so it no longer fires. Handlers that\nreturn a sentinel with no\n[…]\n remain (genuinely unlogged typed-result/predicate outcomes).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 960625fe0d862d054fa0c658dc83f53bee4c2aea)",
          "is_bot": false,
          "headline": "fix(python-lint): SARJ009 exempt logged sentinels + sort diagnostics",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:53:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3316378c1c898a12d2687341a35c5a0bd4c205ca",
          "body": "Two changes to no-fat-try-blocks:\n\n1. Sort diagnostics by (line, col) at the end of check(), matching every\n   peer rule. Previously emitted in ast.walk BFS order, so a fat sibling\n   could precede a deeper nested violation. Flips the xfail-pinned\n   test_multi_violation regression test to assert so\n[…]\nope; mixed handlers (one re-raises, one swallows) still fire.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 41eda7f129e482c7a507488726817b4f7e52f410)",
          "is_bot": false,
          "headline": "fix(SARJ007): sort diagnostics + exempt all-reraise try blocks",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:53:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "35becc9a836ab4f48ee434e1681f92fe931e25e4",
          "body": "A `yield` / `yield from` placed after a `return`/`raise` is the standard\nidiom that forces a function to be a generator even when the yielding path\nis unreachable. Removing it changes the function's type, so it is\nload-bearing, not dead code. Every other unreachable statement after a\nterminal still fires.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 4b2a30f64a978791b6f103c0f95724d08656b093)",
          "is_bot": false,
          "headline": "fix(SARJ010): exempt unreachable yield after a terminal",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:53:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "da2c0adc4cdec40c9af94d1bd1820c9a1ef665fa",
          "body": "…inned rule bugs)\n\nOne agent per rule authored fire/exempt/edge/syntax-error/false-positive-guard\ncoverage across all 22 rules. Strict xfails pin genuine defects for follow-up:\nSARJ012 token-count false positives, SARJ007/SARJ009 missing diag sort,\nSARJ002 async-for/plain-reassign/def-in-loop, SARJ0\n[…]\n f-string/cross-statement ON CONFLICT, SARJ020 filename-gate.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit ea5df5c43ac16897cda5a6b0b5449c19f0c98d08)",
          "is_bot": false,
          "headline": "test(python-lint): exhaustive per-rule suites (2012 tests, 19 xfail-p…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:42:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "67928a145b003e23996e0bbad4c40fb47a107a63",
          "body": "…tured cross-function drift\n\nNarrow SARJ024 to the class where coincidental equality is near-impossible and\ncross-site drift is a real bug, eliminating the false-coupling, description=\nscaffolding, and locality-loss regressions found on bulbul.\n\nThree combined filters replace the old \"any 40+ char r\n[…]\nion=...) scaffolding, and\nOpenAPI example IDs are now silent.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit ff0bf662cfd285da79ca1b895da50da156f57b5d)",
          "is_bot": false,
          "headline": "feat(SARJ024): redesign no-repeated-string-literal to flag only struc…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:42:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1ae073901b0f3e4fb1ce4f796cfdd559247b5ad7",
          "body": "…pers\n\nThe prior rule flagged any private helper defined above ALL of its\nsame-scope callers, anchoring on the first caller's line. For a helper\nshared by several callers that imposes a total order on a call-DAG that\nhas none: stepping below the first caller reads wrong relative to the\nothers, and t\n[…]\nemaining hits are all single-caller and remain\npure reorders.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit c5359e46c549a53ee682dfc17113a8cdaf93fb2d)",
          "is_bot": false,
          "headline": "refactor(SARJ023): restrict stepdown to unambiguous single-caller hel…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:42:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "246db839582ac5121f1cc10d925d88a516e5f6a1",
          "body": "…acronym snake_case\n\nThe old single-public-export rule fired on ANY module with one public\ndef/class whose snake_case name differed from the stem, demanding a rename.\nOn bulbul that produced ~35% regressions: it conflated file identity (the\nmodule's domain) with the sole export's identity (often an \n[…]\nlbul this cuts 67 hits to 8, every remaining one a clear win.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n(cherry picked from commit 228d6b9ceb923137abe975853f765851acde4b87)",
          "is_bot": false,
          "headline": "refactor(python-lint): invert SARJ022 to junk-drawer-stem gate + fix …",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T17:42:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "61f6b5854261b37dce4f3155dd560410321e20f6",
          "body": "…ership\n\n`path.name in {\"conftest.py\"}` -> `== \"conftest.py\"`; the set membership\ntripped ruff SIM in the package's own CI.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017raPjGnjXeCQGjppiVA5ic",
          "is_bot": false,
          "headline": "fix(python-lint): stepdown conftest check trips ruff single-item-memb…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T12:30:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3261319946cd9f1eb50f80bdde65360f5db84839",
          "body": "Pytest convention keeps fixtures/helpers at the top of test modules;\nsibling convention rules already exempt test paths.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017raPjGnjXeCQGjppiVA5ic",
          "is_bot": false,
          "headline": "refactor(python-lint): stepdown skips test paths",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T02:45:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9aa65c0c593d4b17223623799785f0f025152fd5",
          "body": "Modules with several public definitions are out of scope — the rule\nrewards the one-module-one-export shape (filename must match the sole\npublic def/class) instead of mandating it everywhere.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017raPjGnjXeCQGjppiVA5ic",
          "is_bot": false,
          "headline": "refactor(python-lint): SARJ022 fires only on single-export modules",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T02:43:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0ebcb010ccf9938456383c3068b5ecd827880aed",
          "body": "…s, baseline gating, shared parse\n\n- SARJ023 stepdown: a private def/method defined above ALL of its\n  same-scope callers fires; import-time references (decorators, defaults,\n  annotations, class bodies, TYPE_CHECKING) pin the helper and exempt it;\n  recursion cycles, dunders, properties, overloads,\n[…]\n0.9.0 (uvx serves stale cached builds on same-version\n  local installs).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017raPjGnjXeCQGjppiVA5ic",
          "is_bot": false,
          "headline": "feat(python-lint): 0.9.0 — stepdown + no-repeated-string-literal rule…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T02:31:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "16bff4978427d3cc66bdc759a791dbe3dd887af3",
          "body": "# Conflicts:\n#\tpackages/python/src/sarj_python_lint/rules/_registry.py",
          "is_bot": false,
          "headline": "Merge branch 'lint/mined-rules-proto' into lint/single-public-export",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T02:28:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "75d709a882904709e2fd7ed9e64049e9795de73d",
          "body": "…lers\n\nDeterministic core of the stepdown/newspaper rule: flag a private top-level\nfunction or private non-dunder method defined above ALL of its same-scope\ncallers. Exempts cycles, pinned names (module-level/decorator/default/\nannotation/class-body refs), TYPE_CHECKING-only usage, shadowed and dupl\n[…]\nibrated over 184 bulbul files (observability, services, agent, agent/lk,\nstores, webserver): 121 hits, 18 manually inspected, 0 false positives.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(python-lint): SARJ023 stepdown — private helpers below their cal…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T02:27:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a5a6e57b158e2d42ce049aca3b3e31f6c21c15e2",
          "body": "Mined from the sarj-audit magic-values command (\"Repeated Complex String\nLiteral\"): a 40+ char string literal repeated within one module must be\nextracted to a module-level constant so the copies cannot drift.\n\nExclusions tuned on a 174-file bulbul calibration corpus (services, stores,\nwebserver, ag\n[…]\nydantic/FastAPI\nField(examples=[...]) values, and test files. Final run: 32 diagnostics\nacross 17 files, 0 false positives among inspected hits.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(python-lint): SARJ024 no-repeated-string-literal",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T02:25:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "55b90b260667259dc96b4fc9fc99916d9c64afcc",
          "body": "Opt-in rule: a module exposes exactly one public top-level def/class,\nand the filename is that export's snake_case name. Private helpers,\nALL_CAPS constants, __init__.py, conftest.py, and test paths are\nexempt. Not part of any default set — apply per-file where the\none-module-one-export convention is wanted.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_017raPjGnjXeCQGjppiVA5ic",
          "is_bot": false,
          "headline": "feat(python-lint): SARJ022 single-public-export",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-21T01:26:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "06a35647724b06f708e3c416a0cb1d1409c53ee7",
          "body": "[PLT-0000] chore: auto-install sarj-audit Claude Code plugin via repo settings",
          "is_bot": false,
          "headline": "Merge pull request #92 from sarj-ai/chore/claude-sarj-plugin-autoinstall",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-17T12:52:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c76d2986703d2e3f6a22b55d44445fe5c32b3f45",
          "body": "… settings\n\nCommit .claude/settings.json with extraKnownMarketplaces + enabledPlugins so\nClaude Code offers the sarj marketplace and enables sarj-audit for anyone who\ntrusts this repo. Document the org-wide rollout snippet in the README.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "[PLT-0000] chore: auto-install sarj-audit Claude Code plugin via repo…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-17T12:06:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e9d4e95f6b204f4fe9c1699683e0eefb0661f066",
          "body": "[PLT-0000] ci: pass --clear to uv venv",
          "is_bot": false,
          "headline": "Merge pull request #91 from sarj-ai/ci/uv-venv-clear",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-17T11:31:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cebfeb16a02989ce4cff08f5e5fa7c4b3a44e5e9",
          "body": "…venv)\n\nlint-configs CI runs `uv run` (which creates .venv) before the fresh-venv\nwheel test; newer uv errors instead of silently replacing the existing\n.venv. Same guard applied in release.yml.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "[PLT-0000] ci: pass --clear to uv venv (newer uv errors on existing .…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-17T11:25:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9bc6fa9b1d8758673b3f427ab8210c83f15a00ad",
          "body": "[PLT-0000] chore: dependency upgrades + config/version drift fixes",
          "is_bot": false,
          "headline": "Merge pull request #90 from sarj-ai/chore/cleanup-upgrades-version-sync",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-17T11:23:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0f9e5138d84af2f7cb52219df0951efb4fe3ad99",
          "body": "…re-commit hooks\n\n- Port the root .pyright-strict.json hand-edit (reportImplicitOverride off,\n  with rationale) into the lint-configs source of truth; the two files had\n  been out of sync since the initial commit and configs-sync-ci never fired\n  because neither path changed. Bump sarj-lint-configs \n[…]\n-configs-synced.\n- Delete packages/python/.pre-commit-hooks.yaml: pre-commit only reads the\n  repo-root hooks file, which already superseded it.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "[PLT-0000] fix: heal config/version drift, drop stale package-level p…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-17T11:22:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d649292502216dc72e999206ab376e84ea4f89d6",
          "body": "…15.22\n\nTypeScript 7.0.2 is available but blocked: typescript-eslint 8.64 caps its\npeer range at <6.1.0.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "[PLT-0000] chore(deps): upgrade typescript-eslint to 8.64, ruff to 0.…",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-17T11:22:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ec94cad57900cb69f6bcbbe67644ca1b86dc5bf4",
          "body": "[PLT-0000] chore(deps): upgrade standards dependencies to latest",
          "is_bot": false,
          "headline": "Merge pull request #88 from sarj-ai/deps/upgrade-latest",
          "author_name": "Nasr Maswood",
          "author_login": "nmaswood",
          "committed_at": "2026-07-11T17:15:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 0,
      "commits_last_year": 97,
      "latest_release_at": null,
      "latest_release_tag": null,
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 4,
      "days_since_latest_release": null,
      "mean_days_between_releases": null
    },
    "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": "sarj-python-lint",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "Development Status :: 4 - Beta",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: MIT License",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.14",
            "Topic :: Software Development :: Quality Assurance"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/sarj-python-lint/",
          "is_deprecated": false,
          "latest_version": "0.25.0",
          "repository_url": "https://github.com/sarj-ai/standards",
          "versions_count": 30,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 11041,
          "first_published_at": "2026-05-27T18:38:44.359134Z",
          "latest_published_at": "2026-07-27T17:27:25.535004Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "packages/iac/pyrightconfig.json",
        "packages/iac/src/sarj_iac_lint/py.typed",
        "packages/lint-configs/pyrightconfig.json",
        "packages/lint-configs/src/sarj_lint_configs/py.typed",
        "packages/python/pyrightconfig.json",
        "packages/python/src/sarj_python_lint/py.typed",
        "packages/sql/pyrightconfig.json",
        "packages/sql/src/sarj_sql_lint/py.typed",
        "packages/typescript/tests/fixtures/tsconfig.json",
        "packages/typescript/tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 54324,
      "source_files_sampled": 303,
      "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": [],
      "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": 67,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 58
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "nmaswood",
          "commits": 104,
          "avatar_url": "https://avatars.githubusercontent.com/u/10689975?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "configs-sync-ci.yml",
        "heal-tags.yml",
        "iac-ci.yml",
        "lint-configs-ci.yml",
        "python-ci.yml",
        "release.yml",
        "sql-ci.yml",
        "tsconfig-ci.yml",
        "typescript-ci.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": true,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json",
        "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": 9,
            "reason": "29 out of 30 merged PRs checked by a CI test -- score normalized to 9",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 6,
            "reason": "project has 2 contributing companies or organizations -- score normalized to 6",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 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": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "2900c402d5edd6ec9481b5af2ef3233ec75a6283",
        "ran_at": "2026-07-27T17:29:37Z",
        "aggregate_score": 3.7,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-27T17:27:08Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-27T17:26:18Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/sarj-ai/standards",
    "host": "github.com",
    "name": "standards",
    "owner": "sarj-ai"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 44,
      "inputs": {
        "security": 37,
        "vitality": 35,
        "community": 35,
        "governance": 46,
        "engineering": 63
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "at_risk",
        "name": "Vitality",
        "value": 35,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 57,
            "inputs": {
              "commits_last_year": 97,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 4
            },
            "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": "4/52 weeks with commits",
                "points": 2.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "97 commits in the last year",
                "points": 17.9,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 97
                    }
                  }
                ],
                "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": "critical",
            "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": 1,
            "inputs": {
              "releases_count": 0
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "no releases published",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases_published",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "no releases",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases",
                    "params": {}
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "no releases",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 35,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "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": 67,
            "inputs": {
              "packages": [
                "sarj-python-lint"
              ],
              "dependents": null,
              "ecosystems": "pypi",
              "total_downloads": null,
              "monthly_downloads": 11041
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "11,041 downloads/month across pypi",
                "points": 53.9,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 11041,
                      "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": 46,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 16,
            "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 2 contributing companies or organizations -- score normalized to 6",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "at_risk",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 38,
            "inputs": {
              "merged_prs": 67,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 58
            },
            "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": "67/125 decided PRs merged",
                "points": 20.5,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 67,
                      "decided": 125
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 45,
            "inputs": {
              "followers": 9,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "sarj-ai",
              "public_repos": 1,
              "account_age_days": 1014
            },
            "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": "9 followers of sarj-ai",
                "points": 7.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 9,
                      "login": "sarj-ai"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "1 public repos, account ~2 yr old",
                "points": 7.7,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 1
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 2
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "sarj-python-lint"
              ],
              "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": "30 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 30
                    }
                  }
                ],
                "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": 63,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": true,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "9 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 9
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": 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": 6.4,
                "status": "met",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "29 out of 30 merged PRs checked by a CI test -- score normalized to 9",
                "points": 18,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 37,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 37,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 3.7
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "29 out of 30 merged PRs checked by a CI test -- score normalized to 9",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 2 contributing companies or organizations -- score normalized to 6",
                "points": 1.5,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "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": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 3
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 62,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.99,
              "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": "99 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 99,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 71,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json",
                "uv.lock"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [
                "Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "packages/iac/pyrightconfig.json",
                "packages/iac/src/sarj_iac_lint/py.typed",
                "packages/lint-configs/pyrightconfig.json",
                "packages/lint-configs/src/sarj_lint_configs/py.typed",
                "packages/python/pyrightconfig.json",
                "packages/python/src/sarj_python_lint/py.typed",
                "packages/sql/pyrightconfig.json",
                "packages/sql/src/sarj_sql_lint/py.typed",
                "packages/typescript/tests/fixtures/tsconfig.json",
                "packages/typescript/tsconfig.json"
              ],
              "agent_commit_share": 0.83,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Makefile"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "packages/iac/pyrightconfig.json, packages/iac/src/sarj_iac_lint/py.typed, packages/lint-configs/pyrightconfig.json, packages/lint-configs/src/sarj_lint_configs/py.typed, packages/python/pyrightconfig.json, packages/python/src/sarj_python_lint/py.typed, packages/sql/pyrightconfig.json, packages/sql/src/sarj_sql_lint/py.typed, packages/typescript/tests/fixtures/tsconfig.json, packages/typescript/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "packages/iac/pyrightconfig.json, packages/iac/src/sarj_iac_lint/py.typed, packages/lint-configs/pyrightconfig.json, packages/lint-configs/src/sarj_lint_configs/py.typed, packages/python/pyrightconfig.json, packages/python/src/sarj_python_lint/py.typed, packages/sql/pyrightconfig.json, packages/sql/src/sarj_sql_lint/py.typed, packages/typescript/tests/fixtures/tsconfig.json, packages/typescript/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "83 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 83,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 54324,
              "source_files_sampled": 303,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python with type-check config (packages/iac/pyrightconfig.json, packages/iac/src/sarj_iac_lint/py.typed, packages/lint-configs/pyrightconfig.json, packages/lint-configs/src/sarj_lint_configs/py.typed, packages/python/pyrightconfig.json, packages/python/src/sarj_python_lint/py.typed, packages/sql/pyrightconfig.json, packages/sql/src/sarj_sql_lint/py.typed, packages/typescript/tests/fixtures/tsconfig.json, packages/typescript/tsconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "packages/iac/pyrightconfig.json, packages/iac/src/sarj_iac_lint/py.typed, packages/lint-configs/pyrightconfig.json, packages/lint-configs/src/sarj_lint_configs/py.typed, packages/python/pyrightconfig.json, packages/python/src/sarj_python_lint/py.typed, packages/sql/pyrightconfig.json, packages/sql/src/sarj_sql_lint/py.typed, packages/typescript/tests/fixtures/tsconfig.json, packages/typescript/tsconfig.json",
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/303 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 303,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index pypi:sarj-python-lint@0.25.0; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T17:29:57.124064Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/s/sarj-ai/standards.svg",
  "full_name": "sarj-ai/standards",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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