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

GionaGranchelli / tramAI

TramAI is a Kotlin-first JVM runtime for governed AI workflows. It helps teams build AI-powered systems where model calls, tool usage, approvals, data handling, routing, replay-safety, and auditability are treated as first-class runtime concerns rather than scattered application code.

KotlinApache-2.0★ 12 星标⑂ 0 复刻始于 2026年4月在 GitHub 上查看 ↗

GionaGranchelli/tramAI 的健康指数为 100 分中的 54 分,处于「中等」区间。 其得分最高的类别是Engineering Quality(81/100),最低的是Sustainability & Governance(31/100)。 最近一次更新在今天。 近期的大部分工作由 1 位贡献者完成。

54
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

Giona Granchelli个人账户
18 关注者14 个公开仓库始于 2015年4月

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

按类别列示的指标

活力

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

73良好 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 0 天前
9/36提交节奏 — 52 周中有 13 周有提交
18/18提交量 — 最近一年 633 次提交
10/10OpenSSF Scorecard:Maintained — 30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year633
human_commit_share1
days_since_last_push0
active_weeks_last_year13

发布纪律

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

社区与采用

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

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

社区健康

70良好
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(Apache-2.0)
18/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template

可持续性与治理

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

31存在风险 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
0/22.5提交分布 — 头号贡献者编写了 100% 的提交
1.4/13.5贡献者广度 — 1 位贡献者
0/10OpenSSF Scorecard:Contributors — project has 0 contributing companies or organizations -- score normalized to 0
所用输入
bus_factor1
contributors_sampled1
top_contributor_share1
评分方式
0/46.8议题解决 — 0% 的议题已关闭
38.1/38.3PR 接受 — 已裁定的 PR 中 203/204 已合并
0/15OpenSSF Scorecard:Code-Review — Found 0/3 approved changesets -- score normalized to 0
所用输入
merged_prs203
open_issues1
closed_issues0
issue_closed_ratio0
closed_unmerged_prs1
评分方式
10/30所有权背书 — 个人(用户)账户
0/20已验证域名 — 不适用于个人账户
9.2/25所有者影响力 — GionaGranchelli 有 18 位关注者
20.6/25既往记录 — 14 个公开仓库,账户约 11 年
所用输入
followers18
owner_typeUser
is_verified
owner_loginGionaGranchelli
public_repos14
account_age_days4,117
已排除计分(无数据或不适用):已验证域名。 其余权重已重新归一化。

工程质量

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

81良好 · 占总体的 20%

工程实践

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

文档

100优秀
评分方式
30/30README
25/25文档目录
15/15文档 / 主页站点 — https://tramai.dev
10/10仓库描述
10/10主题标签 — 6 个主题标签
10/10Wiki
所用输入
topicsai, kotlin-ai, sovereign-ai, structured-ai, jvm-ai, typed-ai
has_wiki
homepagehttps://tramai.dev
has_readme
has_docs_dir
has_description

安全

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

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

安全态势

40存在风险
评分方式
5.2/7.5Binary-Artifacts — binaries present in source code
2.2/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 3 out of 3 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/3 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
7.5/7.5Maintained — 30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
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
4.5/7.5Vulnerabilities — 4 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate4.1
已排除计分(无数据或不适用):signed_releases。 其余权重已重新归一化。

AI 就绪度

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

72良好 · 占总体的 0%
评分方式
45/45代理指令 — .github/copilot-instructions.md, AGENTS.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 100 次人类提交中有 100 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share1
agent_instruction_files.github/copilot-instructions.md, AGENTS.md
agent_instruction_max_bytes5,513
评分方式
12.6/18一条命令的引导启动 — build-logic/build.gradle.kts, build.gradle.kts, examples/approval-resume/build.gradle.kts(工具链约定,无任务运行器)
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — tramai-dashboard/src/main/frontend/tsconfig.json
10/10可复现环境 — Dockerfile, lockfile
0/10已体现的代理实践 — 最近 100 次提交中没有代理编写的提交
0/8自动化维护 — 未观察到自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfilespackage-lock.json
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configstramai-dashboard/src/main/frontend/tsconfig.json
agent_commit_share0
toolchain_manifestsbuild-logic/build.gradle.kts, build.gradle.kts, examples/approval-resume/build.gradle.kts, examples/governed-workflow/build.gradle.kts, examples/kotlin-native-smoke-example/build.gradle.kts, examples/kotlin-springboot-example/build.gradle.kts, examples/sovereign-document-intelligence/build.gradle.kts, examples/sovereign-offline-verification/build.gradle.kts, examples/sovereign-runtime-consumer-smoke/build.gradle.kts, examples/spring-sovereign-starter/build.gradle.kts, examples/support-agent/build.gradle.kts, examples/tool-governance/build.gradle.kts, tramai-anthropic/build.gradle.kts, tramai-azure-openai/build.gradle.kts, tramai-bedrock/build.gradle.kts, tramai-bom/build.gradle.kts, tramai-core/build.gradle.kts, tramai-dashboard/build.gradle.kts, tramai-deepseek/build.gradle.kts, tramai-embedding/build.gradle.kts, tramai-engine/build.gradle.kts, tramai-gemini/build.gradle.kts, tramai-mcp/build.gradle.kts, tramai-memory-store/build.gradle.kts, tramai-memory/build.gradle.kts, tramai-observability/build.gradle.kts, tramai-ollama/build.gradle.kts, tramai-openai/build.gradle.kts, tramai-orchestration/build.gradle.kts, tramai-persistence-file/build.gradle.kts, tramai-persistence-jdbc/build.gradle.kts, tramai-platform/build.gradle.kts, tramai-rag/build.gradle.kts, tramai-scheduler/build.gradle.kts, tramai-security/build.gradle.kts, tramai-server/build.gradle.kts, tramai-sovereign/build.gradle.kts, tramai-spring-boot-starter-local-provider-openai/build.gradle.kts, tramai-spring-boot-starter-sovereign-ops-actuator/build.gradle.kts, tramai-spring-boot-starter-sovereign-ops-micrometer/build.gradle.kts, tramai-spring-boot-starter-sovereign-ops-observability/build.gradle.kts, tramai-spring-boot-starter-sovereign-ops-rest/build.gradle.kts, tramai-spring-boot-starter-sovereign-ops/build.gradle.kts, tramai-spring-boot-starter-sovereign-persistence-file/build.gradle.kts, tramai-spring-boot-starter-sovereign-persistence-jdbc/build.gradle.kts, tramai-spring-boot-starter-sovereign/build.gradle.kts, tramai-spring/build.gradle.kts, tramai-standalone/build.gradle.kts, tramai-structured/build.gradle.kts, tramai-testing/build.gradle.kts, tramai-vectorstore-chroma/build.gradle.kts, tramai-vectorstore-pgvector/build.gradle.kts, tramai-vectorstore-spi/build.gradle.kts
dependency_bot_commit_share0
评分方式
45/45可类型检查的代码 — Kotlin(静态类型)
54.4/55可控的文件大小 — 采样的 736 个源文件中有 8 个超过 60KB
所用输入
primary_languageKotlin
largest_source_bytes194,020
source_files_sampled736
oversized_source_files8
评分方式
0/40API 模式(OpenAPI/GraphQL/proto)
20/20MCP 服务器
40/40可运行示例 — examples
所用输入
example_dirsexamples
has_mcp_signal
api_schema_files

关键数据

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

数据采集警告

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

更多细节

OpenSSF Scorecard 4.1 / 10
4.1综合

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

7Binary-Artifactsbinaries present in source code
3Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests3 out of 3 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/3 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
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
6Vulnerabilities4 existing vulnerabilities detected
全部依赖 未采集

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

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [
        "ai",
        "kotlin-ai",
        "sovereign-ai",
        "structured-ai",
        "jvm-ai",
        "typed-ai"
      ],
      "is_fork": false,
      "size_kb": 18113,
      "has_wiki": true,
      "homepage": "https://tramai.dev",
      "languages": {
        "Vue": 13575,
        "HTML": 11397,
        "Java": 24870,
        "Shell": 3262,
        "Kotlin": 5806893,
        "Python": 29418,
        "TypeScript": 4784
      },
      "pushed_at": "2026-07-24T07:07:22Z",
      "created_at": "2026-04-18T20:30:45Z",
      "owner_type": "User",
      "updated_at": "2026-07-24T06:25:30Z",
      "description": "TramAI is a Kotlin-first JVM runtime for governed AI workflows. It helps teams build AI-powered systems where model calls, tool usage, approvals, data handling, routing, replay-safety, and auditability are treated as first-class runtime concerns rather than scattered application code.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "master",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "Kotlin",
      "significant_languages": [
        "Kotlin"
      ]
    },
    "owner": {
      "blog": "https://gionag.com",
      "name": "Giona Granchelli",
      "type": "User",
      "login": "GionaGranchelli",
      "company": null,
      "location": "Amsterdam",
      "followers": 18,
      "avatar_url": "https://avatars.githubusercontent.com/u/11965474?v=4",
      "created_at": "2015-04-15T16:53:10Z",
      "is_verified": null,
      "public_repos": 14,
      "account_age_days": 4117
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "0.1.0",
          "kind": "minor",
          "published_at": "2026-04-22T11:41:55Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "b06c9d16267ead14e8e191bb8d50067c3df5b534",
          "body": "…cy-baseline\n\nbuild(0.6.0): capture API and resolved dependency baselines",
          "is_bot": false,
          "headline": "Merge pull request #205 from GionaGranchelli/build/0.6.0-api-dependen…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-24T06:25:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bd53795f708afbb71fd958d23ab910ba5eddcb69",
          "body": "…rTest",
          "is_bot": false,
          "headline": "test: rename DependencyCollectorParityTest to DependencyEdgeNormalize…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-23T15:35:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4889cf405177f5fe8282a0c3dfa23d26151c9201",
          "body": null,
          "is_bot": false,
          "headline": "build(0.6.0): regenerate baseline with correct analyzer SHA",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-23T14:54:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "63f25c76b5ea433f262be5f0897fde2f7547f509",
          "body": null,
          "is_bot": false,
          "headline": "fix: align roadmap TestKit scope, regenerate baseline",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-23T14:53:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "77f614f831547eb993dc2f9fdbbd03883dc07713",
          "body": null,
          "is_bot": false,
          "headline": "build(0.6.0): regenerate canonical baseline with normalized edges",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-23T14:46:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b6459069e9e32aba677ffd72f8a1506786fdc1a2",
          "body": "PR #205 introduces deterministic API and dependency baselines for v0.5.0,\nwith centralized edge normalization, convergence ratchetting, and strict\nAPI validation enforcement.\n\nKey changes:\n- CanonicalGradleProbe: isolated Gradle measurement from detached v0.5.0\n  worktree; generates apiDump via bina\n[…]\nle without API validation = hard failure (not warning)\n- Aggregation fails closed on missing probe outputs\n- Legacy collector removed (collectResolvedDependenciesLegacy)\n- 71 tests across 6 test files",
          "is_bot": false,
          "headline": "build(0.6.0): capture API and resolved dependency baselines",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-23T14:45:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0a108119e1509c2f8d93ce4706707efd4ed4dc0f",
          "body": "…tract-hardening\n\nbuild(0.6.0): harden maintainability baseline contracts and architecture ratchets",
          "is_bot": false,
          "headline": "Merge pull request #204 from GionaGranchelli/build/0.6.0-baseline-con…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T22:12:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9a236b6a70b0fc58b51e114479d050a07a94401f",
          "body": "- '**/build/' already matches only directories named 'build' —\n  it does not match 'build-logic' as a directory name\n- The negation '!/build-logic/src/**' could re-include genuine\n  nested build output under the source tree\n- Tracked source files under build-logic/src/.../build/quality/\n  are unaffected — .gitignore does not apply to tracked files",
          "is_bot": false,
          "headline": "fix: remove unnecessary .gitignore negation",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T21:49:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25ef15211deb532a445f295bb0da9c6a067ed01a",
          "body": "- evaluateRiskWorsening now groups committed findings by identity,\n  sorts risks ascending, and pairs them 1:1 with current findings\n  by sorted position — no longer collapses duplicate identities\n  into a single historical risk entry\n- [low, critical] -> [critical, critical]: exactly 1 worsening\n- \n[…]\n]: 0 worsenings\n- Added 3 regression tests for duplicate-risk scenarios\n- Fixed .gitignore: '**/build/' now excludes build-logic/src/**\n  so source files under dev/tramai/build/quality are not ignored",
          "is_bot": false,
          "headline": "fix: compare duplicate cancellation risks as multisets",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T21:34:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "66269e0a72809f5082c29f08d415ec009069c914",
          "body": "- evaluateRiskWorsening now uses multiset-per-identity risk comparison:\n  committed risks are sorted ascending and paired 1:1 by sorted position\n  with current risks. This correctly handles duplicate identities\n  regardless of source-list ordering\n- [low, critical] → [critical, critical]: exactly 1 \n[…]\nl]: 0 worsenings\n- Removed 7 unused API dump files under examples/*/build/api/ —\n  baseline generator excludes .api files whose path contains 'build',\n  so they contributed nothing to the API baseline",
          "is_bot": false,
          "headline": "fix: multiset risk comparison and remove unused API dumps",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T21:25:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "647a380ec89f80cb9afc41553147406c4a6a8337",
          "body": "- Removed 2247 generated build artifacts (class files, JARs, test\n  reports, etc.) from Git index — only 7 API dumps remain tracked\n- Changed .gitignore from '*/build' to '**/build/' for reliable\n  recursive coverage of all build output directories\n- Fixed multiset delta to compute deltas WITHIN the\n[…]\n test 5 to expect 3 new findings (not 4) — the medium-risk\n  duplicate no longer creates a critical delta\n- Routing tests now pass riskFilter=null since risk worsening\n  inherently crosses risk levels",
          "is_bot": false,
          "headline": "fix: remove tracked build artifacts, fix multiset delta ordering",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T18:39:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a68bce52a5f397c534b57c6706ad0d13543da390",
          "body": "- DeviationBudgetEvaluator now selects exactly delta occurrences per\n  identity instead of all current occurrences of a grown identity\n- Risk-worsening routing tests now call evaluateDeviationBudget()\n  (the production entry point) instead of evaluateRiskWorsening()\n  directly — proves the caller co\n[…]\nget test now includes a new critical catch to actually\n  exercise the matchingAll riskFilter branch\n- Added multiset delta test proving diagnostic reports exact delta,\n  not total filtered occurrences",
          "is_bot": false,
          "headline": "fix: multiset delta accuracy and close test gaps",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T14:14:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d4820b87bbf819c948378f42b505bb22c18303c5",
          "body": "Bare 'build' pattern matched any path containing 'build',\nincluding build-logic/src/. Changed to '/build/' to only\nmatch the top-level build output directory.",
          "is_bot": false,
          "headline": "fix: pin .gitignore 'build' to '/build/' to allow build-logic sources",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T11:26:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0f4ce9427bf4766f53a7fe9b441f79398c748c61",
          "body": "- New DeviationBudgetEvaluator.kt was gitignored by bare 'build' pattern\n  in .gitignore (matched build-logic/ subdirectory)\n- Changed to '/build/' to only match top-level build output\n- Added evaluator source and 4 focused policy-path tests\n\nThe four tests exercise the actual production code paths:\n[…]\nON_RISK_WORSENED failure\n2. cancellationRiskWorsening deviation can authorize it\n3. cancellationCriticalCount deviation cannot authorize it\n4. Non-critical catches don't consume the critical allowance",
          "is_bot": false,
          "headline": "fix: add missing DeviationBudgetEvaluator and test files",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T11:26:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bf3ccb9c1141d972f66af59d42d277d0cb0018ac",
          "body": "…luator\n\n- Extracted DeviationBudgetEvaluator from BaselineVerifier so policy\n  logic can be tested independently without Gradle project fixtures\n- Test 1: low → critical with unchanged identity produces\n  CANCELLATION_RISK_WORSENED failure\n- Test 2: cancellationRiskWorsening deviation authorizes worsening\n- Test 3: cancellationCriticalCount deviation cannot authorize\n  risk worsening (wrong metric)\n- Test 4: non-critical catches do not consume the critical allowance",
          "is_bot": false,
          "headline": "test: add 4 production-path regression tests for deviation budget eva…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T11:17:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba208eb8ed0349e92babe6df0095eba2fe1f6b33",
          "body": "- evaluateRiskWorsening now reads historical risk from actual committed\n  findings instead of reconstructing it from current findings\n- Added riskWorseningMetricName parameter — risk-worsening deviations\n  now search cancellationRiskWorsening, not cancellationCriticalCount\n- matchingAll in evaluateD\n[…]\n applies riskFilter so\n  non-critical catches no longer consume the critical-catch budget\n- Added committedFindings parameter threaded through to risk evaluation\n  for correct low → critical detection",
          "is_bot": false,
          "headline": "fix: risk-worsening detection, metric routing, and budget filtering",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-22T06:13:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "111aefbf421dd98dbdcc9f2d40a2e33c94d36a1b",
          "body": "…spot baseline validation\n\nP1 — Shared aggregate budget evaluator:\n- Extracted evaluateDeviationBudget() — single implementation used by\n  cancellationCriticalCount, cancellationRiskWorsening, globalMutableState,\n  and nondeterminismSources\n- Every metric now uses the same scope-aggregation rule: ea\n[…]\nration\n- Returns max matching value; null when no hotspots match scope\n- Deviation baselines updated to match committed measurements\n  (MQ-0001: 31→32, MQ-0002: 6287→5501, MQ-0004: 1→3, MQ-0005: 7→65)",
          "is_bot": false,
          "headline": "fix(build): address PR #204 4th review — shared budget evaluator, hot…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T20:50:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "80784e9e7dc84c02b1081113be10e96a54e33751",
          "body": "…port, canonical fail-closed, baseline validation, unit tests\n\nP1 — Wildcard cancellation allowance:\n- Per-deviation-scope aggregate budgeting: each deviation's allowed ceiling\n  applies to ALL findings matching its scope, not per-module\n- MQ-0005 (:tramai-* scope, allowed:72) counts critical catche\n[…]\n scope\n- parseScope grammar: all valid forms, invalid forms rejected\n- Deviation baseline mismatch detection\n- Count-delta multiset: duplicate detection, unchanged identities,\n  new identity detection",
          "is_bot": false,
          "headline": "fix(build): address PR #204 3rd review — wildcard allowance, test-sup…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T19:55:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "930e6b995c7926cd99280808a25c8797f558cebc",
          "body": "Closes all remaining findings from the re-review:\n\nP1 — Module catalogue validates against current projects (not committed):\n- verifyModuleCatalog() now called AFTER current baseline generation\n- Validates against current.structural.moduleDependencies.modules\n- Compares classifications with current.\n[…]\ngnostics:\n- BoundaryResult.errors changed from List<String> to List<VerificationDiagnostic>\n- Each parsing error uses proper DiagnosticCode\n- Verifier no longer maps string errors to typed diagnostics",
          "is_bot": false,
          "headline": "fix(build): address PR #204 re-review — remaining P1/P2 issues",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T18:55:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c98226d2a9c65abe7035b4f7fdf005ac7684416a",
          "body": "Resolves all P1/P2 findings from the re-review:\n\nP1 — Module catalogue authority:\n- MeasurementContext now creates ModuleCatalog internally and derives\n  layer/publishability from it in both fromProject and fromDirectory\n- Removed hardcoded publishableNames set and classifyLayerByName()\n- Catalogue \n[…]\nomplete dependency matrix with\n  module-specific allowed edges for pre-existing baseline edges\n- maintainability-deviations.yml: fixed MQ-0002 scope\n  (':root:build.gradle.kts' → '::build.gradle.kts')",
          "is_bot": false,
          "headline": "fix(build): address PR #204 review — contract hardening fixes",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T18:40:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7ffeb3fee655cb5eea1b561b0ccc262bd32ca38a",
          "body": "Generated from clean checkout at 8d2dedf against v0.5.0 worktree.\nModule catalog validation, boundary checks, typed diagnostics, and\nFindingIdentity now verified against canonical baseline.",
          "is_bot": false,
          "headline": "build(0.6.0): canonical baseline referencing analyzer commit 8d2dedf",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T05:59:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8d2dedfc7bb542ee85033ef280fca5095829236f",
          "body": "- Refactored DeviationParser with typed scope grammar, validated diagnostics\n- Updated MaintainabilityBaselinePlugin for new BaselineVerifier constructor\n- Updated maintainability-deviations.yml scopes to validated grammar\n- Synchronized release notes with canonical baseline data",
          "is_bot": false,
          "headline": "fix(0.6.0): remaining verifier and deviation fixes",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T05:58:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fecff4c69698ba8f33d54759220742864de42659",
          "body": "New:\n- ModuleCatalog (config/quality/module-catalog.yml): single authoritative\n  source for module layer, publishability, and API stability\n- ModuleBoundaries (config/quality/module-boundaries.yml): forbidden\n  architectural edge rules (core->framework, published->examples, etc.)\n- FindingIdentity: \n[…]\ner instance\n\nFixed:\n- Release notes (0.6.0-maintainability-baseline.md): correct SHA, metrics\n- Deviation scopes updated to validated grammar\n\nDocs/releases: synchronized with canonical baseline JSON.",
          "is_bot": false,
          "headline": "fix(0.6.0): harden maintainability baseline contracts",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T05:58:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "029dfd172226c1ff8952337b8706c8226afc0e06",
          "body": "build(0.6.0): implement Phase 0 maintainability baseline infrastructure",
          "is_bot": false,
          "headline": "Merge pull request #203 from GionaGranchelli/feat/0.6.0-phase-0-baseline",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T05:39:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a6ccc59c8efcf358bf0b591dd3b2d8353cacf8ea",
          "body": "Generated from clean checkout at 9b1da76 against v0.5.0 worktree.\nBranch-aware rethrow detection (no proximity-based false accepts) and\ncanonical module graph document included.\n\nanalyzerCommitSha: 9b1da76 (branch-aware rethrow + canonical graph doc)",
          "is_bot": false,
          "headline": "build(0.6.0): canonical baseline referencing analyzer commit 9b1da76",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T05:23:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b1da76e05ae7936ca2999f78f1fb55a725781a0",
          "body": "checkRethrowsCancellation now requires 'throw <variable>' to be inside\nthe cancellation-check branch (if variable is CancellationException { ... }),\nnot merely nearby (within 2 lines).\n\nFixes false acceptance of:\n- Cancellation check followed by throw e in unrelated if condition\n- Cancellation check on one line, throw e several lines later\n\nAlso: regenerate module graph Markdown from canonical baseline\n(inventory only, no edges, clearly labelled as canonical mode).\n\n17 tests pass (6 negative).",
          "is_bot": false,
          "headline": "fix(0.6.0): branch-aware cancellation rethrow detection",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-21T05:22:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce76626cf808ee3af7d3f7077335b2bdf525b8da",
          "body": "Generated from clean checkout at b8c682f against v0.5.0 worktree.\nModule paths now normalized to Gradle format (leading colon).\nanalyzerCommitSha: b8c682f (scanner + path normalization + clean gate)",
          "is_bot": false,
          "headline": "build(0.6.0): canonical baseline referencing analyzer commit b8c682f",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-20T21:22:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b8c682f006193c9d5dbd9a49e80d36fb80efe3dd",
          "body": "…yzer gate\n\nScanner fixes:\n- Extract catch variable from catch (e: Type) declaration\n- Require 'throw <variable>' - not just any nearby throw/rethrow\n- Strip comments before scanning for CancellationException references\n\n5 new negative tests:\n- Cancellation check + throw DomainException -> high, not\n[…]\nadle modes produce identical module identities\n\nClean-analyzer gate:\n- generateCanonicalMaintainabilityBaseline now fails if the analyzer\n  checkout has uncommitted changes\n\nAll 16 scanner tests pass.",
          "is_bot": false,
          "headline": "fix(0.6.0): scanner rethrow detection, path normalization, clean-anal…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-20T21:21:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "62d18a104e3c343fb41c94da7ca69df0654c6872",
          "body": "Generated from clean checkout at 38a356f against v0.5.0 worktree.\nThe only change is analyzerCommitSha: 26cd9ed → 38a356f (the\ncommit that contains the scanner fixes and regression tests).\n\nAlso adds docs/ROADMAP-0.6.0.md with the full 0.6.0 roadmap.",
          "is_bot": false,
          "headline": "build(0.6.0): canonical baseline referencing analyzer commit 38a356f",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-20T20:38:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "38a356f2293148d502a06ddd92651468ecd1ccd7",
          "body": "…ne catch joining, regression tests\n\nScanner fixes:\n- findCatchBodyEnd: ignore closing braces on the catch line\n  (e.g.  where  closes the try block).\n  Only counts  from the catch line, then balances forward.\n- checkRethrowsCancellation: two-pass detection handles\n  CancellationException and throw \n[…]\nh preserves suspend position\n- Nested cancellation rethrow is accepted (exact assertion)\n- Project and directory contexts produce identical findings\n\nAll 11 tests pass. Canonical baseline regenerated.",
          "is_bot": false,
          "headline": "fix(0.6.0): deterministic scanner — nested rethrow detection, multili…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-19T10:52:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "26cd9ed8868f78ee90e3e38b9d283cfc8a8bbbd2",
          "body": "Regenerated from clean v0.5.0 worktree with the fixed settings\nparser, shared publishability/layer classification, and deterministic\nscanner. analyzerCommitSha points to the parent commit containing\nMeasurementContext and all analyzer implementation.",
          "is_bot": false,
          "headline": "build(0.6.0): canonical baseline referencing analyzer commit e03f6cd",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-19T10:30:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e03f6cd4fca9ad35ec1dd9672354d1d9ef841e19",
          "body": "…radle modes\n\n- Settings parser handles multi-argument include(...) blocks.\n  No filesystem fallback — directory mode discovers exact same\n  48 modules as Gradle project mode.\n\n- Single authoritative publishability set and layer classification\n  shared between fromProject() and fromDirectory().\n\n- V\n[…]\nt exist and be\n  an ancestor of HEAD (merge-base --is-ancestor).\n\n- Canonical and CI measurements now produce identical populations:\n  480 prod files, 47,750 prod LOC, 219 test files, 71,406 test LOC.",
          "is_bot": false,
          "headline": "fix(0.6.0): measurement equivalence — same modules in canonical and G…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-19T10:29:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bd9bc1518daaed8fafe3f073babff5302a7c5ebd",
          "body": "…terministic scanner, tag→commit→tree verification\n\nP0 provenance fix per PR #203 review:\n\n1. MeasurementContext — decouples all analyzers from Gradle Project.\n   fromDirectory() discovers modules via filesystem walking for\n   canonical worktree generation. fromProject() preserves normal mode.\n\n2. A\n[…]\nworktree.\n   Byte-for-byte reproducible across independent generations.\n   MQ-0006 and MQ-0007 deviations removed (no longer needed).\n\nVerifier: PASSED. No risk worsenings. All provenance gates green.",
          "is_bot": false,
          "headline": "fix(0.6.0): trustworthy canonical provenance — MeasurementContext, de…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-19T09:56:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b55e67cb602cd091fee1ed79413443f658e21b7d",
          "body": "- baselineCommitSha == measuredCommitSha == 5d0ad69b (v0.5.0^{commit})\n- tramaiVersion: 0.5.0\n- workingTreeClean: true\n- measuredSourceTreeHash: populated\n- API dumps: 47 modules",
          "is_bot": false,
          "headline": "build(0.6.0): canonical baseline with correct SHA, version, provenance",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-19T07:26:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8cf5fc5b0b7ca38010b0e9913b9f138487e44c89",
          "body": "…m file\n\n- Use git rev-parse v0.5.0^{commit} for actual commit SHA (not tag object)\n- Add generateCanonicalMaintainabilityBaseline task with provenance checks\n- Verify version against gradle.properties file (not env-overridden property)\n- Revert CI workflow to verify-only\n- GradleException import in plugin",
          "is_bot": false,
          "headline": "fix(0.6.0): annotated tag SHA resolution, canonical task, version fro…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-19T07:25:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d3f7b67931e71260f620b92908b3f175100cbcb0",
          "body": "On feature branches, the committed baseline points to v0.5.0 tag,\ncausing SHA mismatch. Run generateMaintainabilityBaseline first to\nmatch HEAD, then verify against the fresh baseline. This preserves\nall regression checks (cancellation, globals, cycles, hotspots)\nwhile resolving the expected provenance mismatch.",
          "is_bot": false,
          "headline": "fix(ci): generate baseline before verifying in maintainability workflow",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-19T06:15:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c66c1b02dcae8ee06b0741583d733f00900b7fb6",
          "body": "…warning\n\n- 47 BCV API dumps for publishable modules\n- Baseline regenerated with measuredSourceTreeHash and API hashes\n- Empty resolved deps downgraded to warning (Gradle API limitation)\n- Verified: verifier correctly rejects SHA mismatch, dirty tree, empty hash",
          "is_bot": false,
          "headline": "fix(0.6.0): generate API dumps, regenerate baseline, resolved deps → …",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T22:43:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "42e6a726e6517bab0e45b69e8309d039b5af3cbf",
          "body": "Generated via ./gradlew apiDump (47 modules including examples)",
          "is_bot": false,
          "headline": "build(0.6.0): add BCV API dumps for all publishable modules",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T22:41:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "785f2d07a2169134fefbd9f9db898372a3076ee0",
          "body": "… completeness\n\n- computeSourceTreeHash: walks all subproject src/main|test/kotlin|java, build files\n- verifyBaselineIdentity: enforce workingTreeClean, measuredSourceTreeHash, version match\n- verifyMandatorySections: empty API/deps → failures (not warnings)\n- DeviationParser: validate blank id, scope, acceptedAt, owner fields",
          "is_bot": false,
          "headline": "fix(0.6.0): source tree hash covers subprojects, deviation validation…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T22:32:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ef276e5214a6fdbe8501b05f7663d9f56d318334",
          "body": "…ce provenance\n\n- KotlinCancellationCatchScanner.kt: force-add (was gitignored by 'build' path match)\n- KotlinCancellationCatchScannerTest.kt: 9 real scanner tests\n- verifyMandatorySections: empty API/deps → failures (not warnings)\n- verifyBaselineIdentity: enforce workingTreeClean, measuredSourceTreeHash, version match\n- verifyBaselineIdentity: validate tramaiVersion against gradle.properties",
          "is_bot": false,
          "headline": "fix(0.6.0): commit scanner files, make empty API/deps failures, enfor…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T22:31:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1b58b8888cecf67b23c0826cf89d3329d0e58ec7",
          "body": "…rovenance hardening\n\n- KotlinCancellationCatchScanner: extracted from CancellationCatchInventory, directly testable\n- CancellationCatchInventory: simplified to delegate to scanner (34 lines)\n- isInsideStringLiteral: position-based string detection, skips catch in quotes\n- joinCatchLines: multiline \n[…]\nllationCatchScannerTest: 9 tests on real implementation\n- BaselineGenerator: isWorkingTreeClean() + computeSourceTreeHash() provenance\n- BaselineModel: workingTreeClean + measuredSourceTreeHash fields",
          "is_bot": false,
          "headline": "fix(0.6.0): extract testable scanner, fix string literal detection, p…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T21:47:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "df37eb2aed566307916bc82bee56dd3ae62d79e3",
          "body": "…ding-level IDs, provenance\n\n- BaselineGenerator.generateCompleteBaseline(): populates all sections (was empty shell)\n- BaselineVerifier: uses generateCompleteBaseline() + finding-level identity comparison\n- BaselineVerifier: deviation parse errors classified as failures (not just warnings)\n- Baseli\n[…]\ntion, workingTreeClean/measuredSourceTreeHash\n- BaselineGenerator: isWorkingTreeClean() + computeSourceTreeHash() provenance\n- Protocol verification: keys by category+name+value+source (not just name)",
          "is_bot": false,
          "headline": "fix(0.6.0): complete verifier rewrite — generateCompleteBaseline, fin…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T21:43:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "077c042a31f89e9a1c2aac584e88a7e325eb0a1e",
          "body": "- BaselineVerifier: diffs committed vs current, throws GradleException on regressions\n- DeviationParser: validates YAML deviations, matches findings to accepted waivers\n- CancellationCatchInventory: fix catch (e: Exception) regex, fix risk classification order\n- ModuleGraphAnalyzer: production-only \n[…]\noadmap-0.6.0-phase-0.md\n- Deviations: replace placeholder values with real measurements (MQ-0003, MQ-0005)\n- Tests: 5 cancellation scanner tests covering catch syntax, runCatching, risk classification",
          "is_bot": false,
          "headline": "fix(0.6.0): add comparison engine, YAML deviation parser, scanner tests",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T21:07:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "93c84dccfbea6783f638b5c5f6df00ece92a53a8",
          "body": "…tion-only module graph\n\n- BaselineGenerator: baselineCommitSha vs measuredCommitSha, fatal git errors\n- CancellationCatchInventory: fix catch (e: Exception) regex, fix risk order\n- ModuleGraphAnalyzer: exact config matching, canonical paths, separate prod/test\n- BaselineModel: VerificationReport, s\n[…]\nability field, status/note on coverage/mutation\n- Add SnakeYAML, Gradle TestKit, JUnit test dependencies to build-logic\n- Add generateApiBaseline(), generateTestPerformance(), scanDeclarationMetrics()",
          "is_bot": false,
          "headline": "fix(0.6.0): split baseline/measured provenance, scanner fixes, produc…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T21:01:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8af2fd5846f2204c9702ad8a34b3849984e85069",
          "body": null,
          "is_bot": false,
          "headline": "fix(0.6.0): address Phase 0 baseline review findings — P1 corrections",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T20:06:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "46185edaf5b5f73cd84c046d30c55f2c43d7aec0",
          "body": "- ROADMAP-0.6.0.md: complete 12-phase maintainability roadmap\n- roadmpa-0.6.0-Phase0.md: detailed Phase 0 baseline measurement spec",
          "is_bot": false,
          "headline": "docs(0.6.0): add maintainability roadmap and Phase 0 specification",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T19:42:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5d0ad69bb547223f8a5c8639b8398276d35eea50",
          "body": "… gating for $GITHUB_ENV vars\n\n- Add -PsovereignRuntimeVerificationRepo to consumer smoke test command\n  in local-dry-run path (was missing, causing build failure)\n- Replace all if: ${{ env.VAR }} conditions referencing vars set via\n  $GITHUB_ENV (TRAMAI_PUBLISH_MODE, TRAMAI_CAN_REMOTE_PUBLISH) with\n[…]\n (local-dry-run/remote-release) branching\n  - SonarQube analysis gate\n  - Remote publish inputs verification\n  - Signing key verification\n  - Publish to configured repository\n  - Central Portal upload",
          "is_bot": false,
          "headline": "fix(ci): fix publish workflow — consumer smoke repo path, shell-level…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T16:55:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dfc8434f280c8c0cbad4c2dd870ae3e0dc2a5f16",
          "body": "release: prepare TramAI 0.5.0",
          "is_bot": false,
          "headline": "Merge pull request #202 from GionaGranchelli/release/0.5.0",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-18T16:22:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "852c89ba265466c54217557d2dc5db83760691c9",
          "body": "…e before GITHUB_ENV\n\nP2 — Stale coordinates: Replace positive-coordinate check (doc must\ncontain 0.5.0 coordinate) with per-coordinate rejection (every\ndev.tramai coordinate must BE 0.5.0, no mixed 0.5.0+0.4.0 allowed).\nAdd equivalent Maven dependency version validation. Fix 13 stale\n<version>0.4.0\n[…]\nacter injection before writing to\nGITHUB_ENV. Add publish-mode allowlist check (only local-dry-run or\nremote-release accepted). Same newline rejection added to\nsovereign-runtime-release-candidate.yml.",
          "is_bot": false,
          "headline": "fix(review): enforce exact version match on every coordinate, validat…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-17T18:38:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8c92c78cc7cf5b4a1cecb1481be9a528bd5e6206",
          "body": "…map, alignment, runbook\n\nP1 — Security: Replace direct ${{ github.ref_name }} and\n${{ github.event.inputs.* }} shell interpolation with\nstep-level environment variables in both publish.yml and\nsovereign-runtime-release-candidate.yml.\n\nP2 — Roadmap: Update POST-SOVEREIGNTY-ROADMAP.md header from\n'De\n[…]\nv.tramai coordinates reference 0.5.0.\n\nP4 — Runbook: Replace verifyReleaseReadiness with\nverify050ReleaseReadiness in docs/reference/releasing.md,\nnoting it aggregates the base release-readiness task.",
          "is_bot": false,
          "headline": "fix(release): address PR #202 review findings — shell injection, road…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-17T18:24:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "137365744a4d85b61da4105a04d61b173736fa51",
          "body": "- Add ApprovedContinuationResumeQueue and rest-control-plane-enabled\n  references to CHANGELOG Verified section\n- Fix |- typo for PR #188 entry\n- Allow empty tramaiPublishReleaseUrl in signed-bundle guard\n- CI workflow passes empty URL to avoid remote-repo rejection",
          "is_bot": false,
          "headline": "fix(release): restore missing changelog terms for closure docs guard",
          "author_name": "Giovanni",
          "author_login": null,
          "committed_at": "2026-07-16T11:07:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b8cb6a2a5c625abe181d705d12c7da255cc92a8d",
          "body": "… guard\n\n- Fix |- → - for PR #188 changelog entry\n- Allow empty tramaiPublishReleaseUrl in signed-bundle guard\n- CI workflow passes empty URL to avoid remote-repo rejection",
          "is_bot": false,
          "headline": "fix(release): fix changelog typo and CI verifySovereignRuntimeClosure…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-16T10:53:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7b3d4d4b9199d7be961a9c6d2885821d74033037",
          "body": "- Use project dependencies for support-agent (avoids unpublished 0.5.0)\n- Fix absolute path guard to use regex (allows /home/... placeholder)\n- Fix README to state 0.4.0 is latest published, 0.5.0 is RC\n- Add tramaiReleaseDate to gradle.properties; use property in guards\n- Align release date to 2026-07-16\n- Remove duplicate PR #199, #200 changelog entries\n- Add duplicate PR detection guard\n- Wire verify050ReleaseReadiness into check and publish workflow",
          "is_bot": false,
          "headline": "fix(release): address PR #202 review findings",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-16T10:41:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb158542e29988818a1fcea9146096f96c89f4b7",
          "body": null,
          "is_bot": false,
          "headline": "release: prepare TramAI 0.5.0",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-16T09:31:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aad4256fb09d5df31e6191e87a93d097b71fa682",
          "body": "example(tooling): add governed tool permission example",
          "is_bot": false,
          "headline": "Merge pull request #201 from GionaGranchelli/example/tool-governance",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-16T09:05:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "087dc1175d515c6c182f86b2fa379fdd7877f594",
          "body": "- Pass sensitive tool-call arguments through provider, not service input\n- Replace inline SHA-256 digesters with Sha256ToolArgumentsDigester\n- Assert exposure ALLOW in DENY and REQUIRE_APPROVAL tests\n- Use :run as primary command in matrix and guide\n- Strengthen documentation guard for matrix row\n- Rename AuditStreamIdResolver to FixedAuditStreamIdResolver\n- Update privacy test with correct DeterministicToolProvider API",
          "is_bot": false,
          "headline": "fix(tool-governance): address final PR review items",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-14T14:08:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d4520b5508b6900a6a89be7634464b1ade0e219",
          "body": "Removes the double-pipe prefix on the 'Tool-governance usage example'\nrow in the remaining 0.5.0 work table. The verify guard rejects lines\nbeginning with ||.",
          "is_bot": false,
          "headline": "fix(roadmap): remove malformed || table row",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-14T12:18:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "74b77b1ad1884fdb58679de4b80c594a2b192ab1",
          "body": "- Fix malformed || table row and duplicate task #6 in roadmap\n- Add application plugin and mainClass for :run support\n- Restore :run as primary verify guard\n- Replace vacuous eventType partition check with event-ID based proof\n- Add serialized evidence privacy test with sensitive arguments\n- Correct PaymentTool comment reference",
          "is_bot": false,
          "headline": "fix(tool-governance): address PR #201 review findings",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-14T11:59:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "309de0e3c0a5769ed778842d0cd481b1546c79a4",
          "body": "Adds a new examples/tool-governance/ module demonstrating three deterministic\ntool governance scenarios with the dedicated tool.permission evidence family:\n\n1. customer_lookup (ALLOW) — LOW risk, AUTO approval, executes once\n2. account_delete (DENY) — CRITICAL risk, denied at BEFORE_TOOL_EXECUTION\n \n[…]\nboundaries\n- verifyToolGovernanceExample Gradle task wired into check\n- Updated example selection guide, tool-calling guide, tool permission\n  model, roadmap, STATUS.md, and CHANGELOG\n\nCloses PR #201.",
          "is_bot": false,
          "headline": "example(tooling): add governed tool permission example",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-14T11:43:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5ef04c737ed020497623949684969709d718bf10",
          "body": "…time-evidence\n\nfeat(evidence): add tool.permission runtime evidence family",
          "is_bot": false,
          "headline": "Merge pull request #200 from GionaGranchelli/feat/tool-permission-run…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-14T11:12:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "032902bfbc3ddcc50e9097e528ab1491dd697ec6",
          "body": "P1 — Removed 31 accidental double-pipe table-row prefixes (25 in\nroadmap, 6 in tool-permission-model) that broke the Gradle guard\nrejecting '||' at line start in the roadmap document.\n\nP2 — Corrected Phase 6 task 5: from 'generic policy.decision audit\nand evidence paths' to 'generic policy audit path and dedicated\ntool.permission evidence path'.\n\nP3 — Consolidated duplicate 'MCP connector support' non-claim\nbullets in tool-permission-model.md into one.",
          "is_bot": false,
          "headline": "docs: fix malformed table pipes, stale task wording, and duplicate claim",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-14T10:58:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "28cd31dc5d5f8942ef74c9742e3ce8c4daf2a9fa",
          "body": "P2 — Updates three authoritative documentation files to reflect that\nthe dedicated tool.permission runtime evidence family (PR #200) is\nnow implemented:\n\ndocs/security/tool-permission-model.md:\n- Status header updated to include implemented evidence\n- Permission decisions table lists only three impl\n[…]\ncated evidence items (all complete)\n\ndocs/STATUS.md:\n- Implemented section: added JavaBean DTO schema, bundle wiring,\n  dedicated tool.permission evidence\n- Incomplete section: removed completed items",
          "is_bot": false,
          "headline": "docs: mark tool.permission evidence as implemented in canonical docs",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-14T08:29:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "97498595f3313d906aefc81049e28fd7c1875947",
          "body": "P3 — runtime-evidence-export-model.md: fix three table rows that had\nstray leading pipes (||| instead of |), making them render correctly.\n\nP3 — runtime-evidence-bundle-map.md:\n- Fix four-column table separator (was incorrectly five columns)\n- Update 'three JSONL files' to 'four JSONL files' for consistency\n  with the new tool-permissions.jsonl family",
          "is_bot": false,
          "headline": "docs(evidence): fix table formatting and copy in documentation",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T22:14:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79724df4283e7ad8ff262a747b56e140af946de1",
          "body": "…g, docs\n\nCompletes the full tool.permission evidence family by addressing all\nreview findings from round 1:\n\nP1 — Writer and verifier now consistent:\n- Added tool.permission to verify-evidence-bundle.sh: file mapping,\n  decision allowlist, source component, metadata keys, reasonCode\n  format, famil\n[…]\nt from the top-level audit field\n\nP1 — Retargeted to master:\n- Rebased onto origin/master (PR #199 merged)\n- PR #200 will be retargeted to master\n\nDocs: export model, bundle map, and CHANGELOG updated",
          "is_bot": false,
          "headline": "fix(evidence): address PR #200 review — verifier, lifecycle, filterin…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T22:06:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "83ba8ccb6583f304bfcb6c1e8370fa48a0c61351",
          "body": "The exporter now adds the audit event's top-level enforcementPoint\ninto the safe metadata map, since enforcementPoint is a required\nmetadata field per the spec (not just a top-level audit field).\n\n- ToolPermissionRuntimeEvidenceExporter: always includes enforcementPoint\n  from event's top-level fiel\n[…]\nn the exported metadata\n- Updated unit test assertions to expect enforcementPoint in metadata\n- Integration test now passes (was asserting enforcementPoint in metadata\n  but exporter wasn't adding it)",
          "is_bot": false,
          "headline": "fix(evidence): include enforcementPoint in tool.permission metadata",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T22:02:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "956d0267fdde40a0e9fec0ccd763cb73c31cbe71",
          "body": "Implements a dedicated tool.permission runtime evidence family for\ntool enforcement events (BEFORE_TOOL_EXPOSURE, BEFORE_TOOL_EXECUTION,\nBEFORE_TOOL_RESULT_REINJECTION), partitioned from policy.decision.\n\nChanges:\n- New ToolPermissionRuntimeEvidenceExporter — converts tool enforcement\n  AuditEvents \n[…]\n: 5 regression tests\n- ToolPermissionRuntimeEvidenceExporterTest: 24 tests (all passing)\n- ToolExecutionDenialEvidenceIntegrationTest: updated to use the\n  new exporter for tool enforcement assertions",
          "is_bot": false,
          "headline": "feat(evidence): add tool.permission runtime evidence family",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T22:02:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "64b413c6bb5775738f5d4f0de2d19cd14abce39b",
          "body": "…ndle-wiring\n\nfeat(evidence): wire runtime decisions into sovereign evidence bundles",
          "is_bot": false,
          "headline": "Merge pull request #199 from GionaGranchelli/feat/runtime-evidence-bu…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T20:54:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a6dc10d97de3b6f0b964da08001dad7e65dfc58",
          "body": "P2 — ManifestJsonReader now uses Jackson ObjectMapper with:\n  - FAIL_ON_TRAILING_TOKENS (rejects trailing content after JSON)\n  - STRICT_DUPLICATE_DETECTION (rejects duplicate keys)\n  - No ALLOW_TRAILING_COMMA (trailing commas rejected by default)\n\nThis eliminates all edge cases in the custom parser\n[…]\nobjects and arrays are validated\n- JSON escape sequences are validated\n- All duplicate keys are tracked, not only duplicate bundleType\n\nAlso made jackson-databind a compile dependency (was test-only).",
          "is_bot": false,
          "headline": "fix(evidence): replace custom JSON parser with Jackson for manifest.json",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T20:00:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "811c1226680ef5fad48460b8fac52f18e42493ee",
          "body": "…manifest parsing\n\nP1 - Fail closed on ambiguous recovery state\n  - Both target and backup existing now unconditionally errors out\n    instead of trying a heuristic validity check that could delete a\n    good backup while missing corrupted or superficially valid targets.\n  - Removed isValidEvidenceS\n[…]\ndetection' → 'correctly rejected'\n\nUpdated tests 28 and 32 (stale backup, both-exist scenarios) to\nreflect fail-closed behavior: now expect IllegalStateException\nand verify both directories preserved.",
          "is_bot": false,
          "headline": "fix(evidence): address round-3 review — fail-closed recovery, strict …",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T19:25:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "de5c023ca0830837911e442f26930c20c73ecd0d",
          "body": "… review fixes\n\n- Fix build.gradle.kts runtime-evidence tamper test: verify without\n  re-finalizing so stale-manifest detection actually fires; restore\n  original file content after tamper test instead of re-finalizing\n  corrupted state\n- Accept 'unknown root field' as valid verifier failure message\n[…]\nnormalized paths for single-segment dirs\n- ManifestJsonReader: requires commas between JSON object properties\n- 7 new unit tests covering contract validation, recovery, path safety,\n  and JSON parsing",
          "is_bot": false,
          "headline": "fix(evidence): complete lifecycle test and finalize remaining PR #199…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T18:14:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6eb5636682426b86e5d571cf10d52cc6f9adc742",
          "body": "…lidation, crash recovery, JSON parsing\n\n- Add family-specific metadata value validation to verify-evidence-bundle.sh:\n  approval reasonDigest/eventKeyDigest digest format, reasonLength >= 0,\n  approvalVersion >= 0; routing *Digest digest format, routeIndex >= 0,\n  attempt >= 0, six-code fallbackRea\n[…]\n),\n  symlinked manifest rejection, manifest JSON parsing edge cases\n- Remove unused temp-dir-in-bundle check from tests\n- All tests pass: tramai-security, integration, verifySovereignLabEvidenceBundle",
          "is_bot": false,
          "headline": "fix(evidence): address round-2 review findings — verifier metadata va…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T15:04:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "52da833cd531ddc02e45b5a6246c0656be1df91f",
          "body": "… machine, temp dir outside bundle\n\n- Add ManifestJsonReader: a minimal proper JSON parser (not string slicing)\n  for extracting bundleType from manifest.json. Handles reordered properties,\n  pretty-printed JSON, trailing-property, escaped strings.\n- Move temp directory to sibling of bundle root (no\n[…]\n target+backup states: exists/absent → normal/recovery/ambiguous/none\n  If backup exists and target is missing, restore before proceeding\n- Add symlink rejection for manifest.json in bundle root guard",
          "is_bot": false,
          "headline": "fix(evidence): address re-review — JSON parsing, crash recovery state…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T14:58:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "801095426322f93c3a192f9db4e71b32edb255b4",
          "body": "…, reason-code allowlists\n\n- Require bundleDirectory/manifest.json with bundleType=\"sovereign-lab-evidence-bundle\"\n  before any write (dependency-free string extraction, no Jackson)\n- Replace generic reasonCode format regex with family-specific allowlists:\n  approval: approval-approved/approval-deni\n[…]\nries)\n- Add negative tests for missing/wrong manifest and allowlist-violating reasonCodes\n- Update integration test with same bundle root guard\n- All tests pass; verifySovereignLabEvidenceBundle green",
          "is_bot": false,
          "headline": "fix(evidence): address PR #199 remaining findings — bundle root guard…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T10:57:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0db77e85298e622ede543dadd3ab0d0dfe875a61",
          "body": "…ement, contract validator, verifier hardening\n\n- P1: Replace fixed .tmp and delete-first replacement with unique temp dirs\n  + backup-based transactional strategy (backup → replace → delete/restore)\n- P1: Implement RuntimeEvidenceContractValidator ensuring writer/verifier parity:\n  source.component\n[…]\necycle test (create → write → verify cleanup → assert\n  content), global duplicate detection test, PII reasonCode rejection test,\n  stale backup cleanup test, negative routeIndex/metadata digest tests",
          "is_bot": false,
          "headline": "fix(evidence): address PR #199 review findings — transactional replac…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T10:46:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "94d92c9608803e2e7305d438eee33f356faabb24",
          "body": "PR #199 — Runtime evidence bundle wiring\n\nRuntimeEvidenceBundleWriter groups RuntimeEvidenceRecord objects by event\ntype and atomically writes them into the bundle's runtime-evidence/\nsection as policy-decisions.jsonl, approval-decisions.jsonl, and\nprovider-routing.jsonl. Fail-closed validation chec\n[…]\nintegration test. All existing tests\npass.\n\nDocumentation: updated bundle map, export model, evidence chain,\nEVIDENCE.md operator flow, reviewer guide, release readiness checklist,\nroadmap, changelog.",
          "is_bot": false,
          "headline": "feat(evidence): wire runtime decisions into sovereign evidence bundles",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T07:53:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4d8d5a78388931dc266da51853cf77e12750e7ba",
          "body": "…d-output-schema\n\nfeat(structured): generate schemas for JavaBean DTOs",
          "is_bot": false,
          "headline": "Merge pull request #198 from GionaGranchelli/feat/java-bean-structure…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T07:28:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6cdf75b39bce21e9b43a36d664604cf708ab78fd",
          "body": "… STATUS table, array extraction (round 3)\n\n- P1: Restored POST-SOVEREIGNTY-ROADMAP.md from master (was accidentally\n  overwritten) — only changed the JavaBean row to ✅ Complete — PR #198\n- P1: Restored structured-output-contract-lifecycle.md from master — merged\n  JavaBean sections into Stage 2 (di\n[…]\nded 3 new tests: root generic JavaBean @AiRange enforcement,\n  prefixed array extraction, valid generic envelope happy path\n- P3: Restored valid nested collection test (was accidentally lost in patch)",
          "is_bot": false,
          "headline": "fix(structured): restore canonical docs, fix generic post-validation,…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T07:10:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "10057f308c3e18efb315aa9739d7309f205d15b3",
          "body": "- P1: Generalized validateJsonShape() handles all root types (List<T>,\n  Kotlin objects, JavaBeans) — no longer root-JavaBean-only\n- P1: validateJavaJsonShape() mirrors schemaForJavaType() recursively:\n  scalar→no-op, Collection→recurse items, JavaBean→check keys+recurse,\n  Map→unsupported\n- P1: Rem\n[…]\nve, null nested in list,\n  nested collection missing, generic envelope, Map subclass rejection,\n  Kotlin-wraps-JavaBean primitive, valid root list, valid nested\n  collection) — 50 total JavaBean tests",
          "is_bot": false,
          "headline": "fix(structured): address PR #198 second-review findings (round 2)",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-13T06:56:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e37c56a5ad4860f34aaea2a5b4c1f8b8f3bfe6ef",
          "body": "- P1: Pre-deserialization required-key validation for primitive fields\n  (missing int/double/boolean properties now fail with clear error)\n- P1: Active-path recursion context (add/remove) for sibling equality +\n  explicit error on recursive types instead of stack overflow\n- P1: Write-only property e\n[…]\nnstead of\n  KClass.createType() conversion\n- P2: STATUS.md table row fixed\n- P3: 28 tests total (up from 14), all with exact structural assertions\n- P3: JavaBeanSchemaContext made private nested class",
          "is_bot": false,
          "headline": "fix(structured): address PR #198 review findings (round 1)",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T20:14:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3de3d92fb97921e1768198918c6a6c442c13cd1b",
          "body": "- Add JavaBean detection via @Metadata annotation to preserve Kotlin path\n- Jackson introspection discovers Java properties (setter/writable field only)\n- Parallel schema path: schemaForJavaType() mirrors schemaForType()\n- All discovered JavaBean properties are required (fail-closed)\n- @AiDescriptio\n[…]\nproperties excluded\n- Maps remain explicitly unsupported\n- 14 JavaBean-specific tests + updated Java standalone smoke\n- CHANGELOG.md and STATUS.md updated\n- Existing Kotlin schema/validation unchanged",
          "is_bot": false,
          "headline": "feat(structured): generate schemas for JavaBean DTOs (PR #198)",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T19:38:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4755e410585e8cf47232267c5fecfc496caa388d",
          "body": "…baseline\n\nchore(release): establish TramAI 0.5.0 development baseline",
          "is_bot": false,
          "headline": "Merge pull request #197 from GionaGranchelli/chore/0.5.0-development-…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T18:52:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5c8ed2079a8a95cd8d70dd2ff70641bfcb4d410c",
          "body": "- Set gradle.properties to 0.5.0-SNAPSHOT, root fallback to 0.5.0-SNAPSHOT\n- Record 0.4.0 as latest published stable release with verified date (2026-07-06)\n- Add verifyDevelopmentVersionAlignment guard wired into check\n- Update CHANGELOG.md with target release annotation and PR #197 entry\n- Update \n[…]\nadditions\n- Update releasing doc example version\n- Remove stale KSP-in-0.4.0 promise from architecture overview\n- Preserve historical 0.3.1 release records\n- No runtime behavior or public APIs changed",
          "is_bot": false,
          "headline": "chore(release): establish TramAI 0.5.0 development baseline",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T18:08:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ad0345647c05b2c34bc03d1bcbd7e2865cb7a184",
          "body": "…mparison\n\ndocs(comparison): position TramAI alongside Spring AI and LangChain4j",
          "is_bot": false,
          "headline": "Merge pull request #196 from GionaGranchelli/docs/jvm-ai-framework-co…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T14:05:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6ae5ed59f759ee8d3bc9d06a0bd1ff8e35e4347a",
          "body": "- Scoped Spring AI, LangChain4j, TramAI term checks to their relevant sections\n  using sectionBetween() which was defined but never called\n- Scoped maturity acknowledgements to Spring AI / LangChain4j / TramAI sections\n- Scoped coexistence boundaries to the Coexistence section\n- Added row-level comparison matrix checks (5 key rows)\n- Fixed broken roadmap link: ../comparison/ → comparison/ (docs-relative)\n- Updated logger output to reflect section-scoped verification",
          "is_bot": false,
          "headline": "docs(comparison): section-scope verification guard, fix roadmap link",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T13:12:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca1e8da50785eb4a4ac08d0bc8013ab9c662ff6c",
          "body": "Add a dated, official-source comparison of TramAI 0.3.1, Spring AI 2.0.0,\nand LangChain4j 1.17.2. The document provides selection criteria for each\nframework, documents shared capabilities, acknowledges where TramAI is\nweaker, and covers coexistence patterns. Includes verification guard.\n\nPhase 7 (Product Narrative and Adoption) completes with this PR.\n\nCloses: #196",
          "is_bot": false,
          "headline": "docs(comparison): position TramAI alongside Spring AI and LangChain4j",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T12:51:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6eebfabe750ab6c533e001d56ebafbdd875d1785",
          "body": "…uide\n\ndocs(examples): add example selection guide",
          "is_bot": false,
          "headline": "Merge pull request #195 from GionaGranchelli/docs/example-selection-g…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T07:15:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "374ad712cbb3f6b3218440a077106e5ff8d592d8",
          "body": "…equisites\n\n- Change matrix 'External infrastructure' from 'Controlled network environment'\n  to 'Docker + Python 3' to match the detailed profile\n- Add matrix-scoped guard check so the row cannot drift from the profile",
          "is_bot": false,
          "headline": "docs(examples): align offline-verification matrix with corrected prer…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T07:05:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58fda047c1146aebbdd4a5bad44915424686775d",
          "body": "… accuracy\n\nP2 fixes from review:\n- Restore Governed Workflow Testing row in root README (was replaced not supplemented)\n- Correct two examples/sovereign-lab/README.md references → sovereign-lab/README.md\n- Document Docker, Python 3, and --network=none for offline verification\n- Replace nonexistent \n[…]\nilesystem existence; prohibit duplicated examples/ prefix\n- Add section-scoped guard checks: @AiDescription, @Structured prohibition, Docker,\n  Python 3, --network=none, gemma4:e4b, deepseek-r1:8b-64k",
          "is_bot": false,
          "headline": "docs(examples): fix navigation, prerequisites, annotations, and guard…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T07:00:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3635505ab713b57e0aa05339671d1ad41d47f00a",
          "body": "- Create examples/README.md — authoritative guide covering all 8 TramAI\n  example paths: governed-workflow, support-agent, kotlin-springboot-example,\n  approval-resume, spring-sovereign-starter, sovereign-document-intelligence,\n  sovereign-offline-verification, and sovereign-lab.\n- Each profile docu\n[…]\nrases, nav target existence, settings.gradle.kts module\n  inclusion, section-scoped per-profile checks, forbidden claims, and\n  premature competitor comparison prohibition. Wired into ./gradlew check.",
          "is_bot": false,
          "headline": "docs(examples): add example selection guide",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T06:41:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "51be5b1f0d15431920e3d01af4c324a0b3406e6d",
          "body": "…ow-article\n\ndocs(article): draft governed JVM AI workflow article",
          "is_bot": false,
          "headline": "Merge pull request #194 from GionaGranchelli/docs/governed-jvm-workfl…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-12T06:11:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3f703ed66ba28c737766aac1c1c5f6cc6abf56e5",
          "body": "…, evidence claims, and talk schedule\n\nP2 fixes from review:\n- Replace readyForReview() placeholder with actual ClaimTriageResult construction\n  and .build {} terminal to match the runnable source\n- Correct policy-gate explanation: classification already executed before the\n  restricted gate; gate p\n[…]\nmin)\n- Guard: add snippet authenticity check (.build/ClaimTriageResult), new forbidden\n  phrases (record every decision, every governance decision, evidence export\n  worker, automatically exported as)",
          "is_bot": false,
          "headline": "docs(article): fix snippet accuracy, policy sequencing, routing table…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T21:59:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c7ddc52faf73ffc4949e49327f693418f8b73694",
          "body": "- Add publishable article: Beyond the Model Call — Governed AI Workflows for the JVM\n  Covers the full narrative: model calls are easy, prompts are not enforcement,\n  claim-triage workflow, policy before side effects, approval lifecycle,\n  controlled routing, evidence and recovery, JVM architecture,\n[…]\nlowArticle guard: validates headings, required phrases,\n  link target existence, talk outline sections, forbidden claims, and premature\n  competitor comparison prohibition. Wired into ./gradlew check.",
          "is_bot": false,
          "headline": "docs(article): draft governed JVM AI workflow article",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T21:18:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f94b301a95cf9225dd1e82e60d21ea2bc4670d00",
          "body": "…kflows\n\ndocs(readme): rewrite README around governed workflows",
          "is_bot": false,
          "headline": "Merge pull request #193 from GionaGranchelli/docs/readme-governed-wor…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T19:46:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b5a8c037f595d4c07daf7f1f3b1b60af019022cc",
          "body": "…n claim, strengthen verification guard\n\n- Replace broken architecture overview and module matrix links with correct paths\n- Remove unsupported network-destination enforcement claim; qualify deny-by-default as configuration-dependent\n- Change JDK 21 recommendation to explicit JVM 21+ toolchain requirement\n- Strengthen verifyReadmePositioning guard: enforce first-Gradle-command ordering, validate all navigation targets exist",
          "is_bot": false,
          "headline": "docs(readme): fix broken links, remove unsupported network-destinatio…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T19:01:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ade8bd4518089be6beb1cdb49831b13e42a6e19a",
          "body": "PR #193 — Phase 7, Epic 7.\n\nComplete README rewrite organized around the canonical product\npositioning and a zero-credential governed workflow first-run path.\n\nStructure:\n- Header with canonical tagline and active-development notice\n- 'Why Governed Workflows' contrast table\n- Runnable governed-workf\n[…]\nse-insensitive forbidden-claim checks, absence of premature\n  competitor comparisons, and absence of stale roadmap language.\n\nNo runtime behavior, public API, example, or provider integration\nchanges.",
          "is_bot": false,
          "headline": "docs(readme): rewrite README around governed workflows",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T13:51:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9d5661b94973e4b9e4bf491be397c0ede634ce2c",
          "body": "docs(product): define TramAI positioning",
          "is_bot": false,
          "headline": "Merge pull request #192 from GionaGranchelli/docs/product-positioning",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T13:40:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "475a6c96a9b6aa66388febe2ec10fcf604e2eff9",
          "body": "…ngthen guard\n\nP2 — Product pillars and claim boundaries now qualify enforcement\nand evidence as configured capabilities (not unconditional defaults):\ngovernance requires explicit configuration, routing 'can prevent',\naudit evidence 'can be emitted'. Absolute 'enforces', 'routes',\n'produces' → 'supp\n[…]\n\nP3 — PRODUCT-THESIS.md: 'preserved for reference' → 'summary of\nthe superseded historical positioning is retained'; (.) link → ./.\n\nP3 — Roadmap #192 row is now a real link to product/positioning.md.",
          "is_bot": false,
          "headline": "fix(pr192): qualify enforcement claims, complete MCP correction, stre…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T13:17:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a1e84de8e4833c8ba0ca472fa782f6762bd32bfd",
          "body": "PR #192 — Phase 7, Epic 7.\n\nCreates the canonical product positioning document at\ndocs/product/positioning.md with:\n\n- Tagline: 'Governed AI workflows for the JVM.'\n- One-sentence positioning and thirty-second description.\n- Problem thesis (6 concrete pain points).\n- Product category: governed AI wo\n[…]\nd sections, canonical\n  tagline, forbidden claims, old thesis redirect, MCP server\n  acknowledgment, and PR #192 in roadmap.\n\nNo runtime behavior, public API, example, or provider integration\nchanges.",
          "is_bot": false,
          "headline": "docs(product): define TramAI positioning",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T13:04:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fd7b8051f94eda9674bc22d938b84c6448f5a5ac",
          "body": "…cy-denial\n\ntest(tooling): prove fail-closed tool execution denial",
          "is_bot": false,
          "headline": "Merge pull request #191 from GionaGranchelli/test/tool-execution-poli…",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T12:45:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "817fdc5c0bc664f48370040f58da78a2857b1237",
          "body": "P2 — Audit-ordering test now asserts job.isActive and\nexceptionRef==null BEFORE releasing the emitter. This proves the\ninvocation is frozen mid-audit — the caller has not received the\nexception yet. Closes the original reviewer concern that a\nhypothetical async implementation could satisfy the previ\n[…]\nr tool\ninvocation' → 'Audit tool exposure and execution policy decisions'\nand 'Add denied-tool evidence path' → 'Verify denied-tool execution\nthrough generic policy.decision audit and evidence paths'.",
          "is_bot": false,
          "headline": "fix(pr191): close remaining audit-ordering, privacy, and doc gaps",
          "author_name": "Giona Granchelli",
          "author_login": "GionaGranchelli",
          "committed_at": "2026-07-11T12:19:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 1,
      "commits_last_year": 633,
      "latest_release_at": "2026-04-22T11:41:55Z",
      "latest_release_tag": "0.1.0",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 13,
      "days_since_latest_release": 92,
      "mean_days_between_releases": null
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 57,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 0,
      "stars": 12,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tramai-dashboard/src/main/frontend/tsconfig.json"
      ],
      "toolchain_manifests": [
        "build-logic/build.gradle.kts",
        "build.gradle.kts",
        "examples/approval-resume/build.gradle.kts",
        "examples/governed-workflow/build.gradle.kts",
        "examples/kotlin-native-smoke-example/build.gradle.kts",
        "examples/kotlin-springboot-example/build.gradle.kts",
        "examples/sovereign-document-intelligence/build.gradle.kts",
        "examples/sovereign-offline-verification/build.gradle.kts",
        "examples/sovereign-runtime-consumer-smoke/build.gradle.kts",
        "examples/spring-sovereign-starter/build.gradle.kts",
        "examples/support-agent/build.gradle.kts",
        "examples/tool-governance/build.gradle.kts",
        "tramai-anthropic/build.gradle.kts",
        "tramai-azure-openai/build.gradle.kts",
        "tramai-bedrock/build.gradle.kts",
        "tramai-bom/build.gradle.kts",
        "tramai-core/build.gradle.kts",
        "tramai-dashboard/build.gradle.kts",
        "tramai-deepseek/build.gradle.kts",
        "tramai-embedding/build.gradle.kts",
        "tramai-engine/build.gradle.kts",
        "tramai-gemini/build.gradle.kts",
        "tramai-mcp/build.gradle.kts",
        "tramai-memory-store/build.gradle.kts",
        "tramai-memory/build.gradle.kts",
        "tramai-observability/build.gradle.kts",
        "tramai-ollama/build.gradle.kts",
        "tramai-openai/build.gradle.kts",
        "tramai-orchestration/build.gradle.kts",
        "tramai-persistence-file/build.gradle.kts",
        "tramai-persistence-jdbc/build.gradle.kts",
        "tramai-platform/build.gradle.kts",
        "tramai-rag/build.gradle.kts",
        "tramai-scheduler/build.gradle.kts",
        "tramai-security/build.gradle.kts",
        "tramai-server/build.gradle.kts",
        "tramai-sovereign/build.gradle.kts",
        "tramai-spring-boot-starter-local-provider-openai/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops-actuator/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops-micrometer/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops-observability/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops-rest/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-persistence-file/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-persistence-jdbc/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign/build.gradle.kts",
        "tramai-spring/build.gradle.kts",
        "tramai-standalone/build.gradle.kts",
        "tramai-structured/build.gradle.kts",
        "tramai-testing/build.gradle.kts",
        "tramai-vectorstore-chroma/build.gradle.kts",
        "tramai-vectorstore-pgvector/build.gradle.kts",
        "tramai-vectorstore-spi/build.gradle.kts"
      ],
      "largest_source_bytes": 194020,
      "source_files_sampled": 736,
      "oversized_source_files": 8,
      "agent_instruction_files": [
        ".github/copilot-instructions.md",
        "AGENTS.md"
      ],
      "agent_instruction_max_bytes": 5513
    },
    "dependencies": {
      "manifests": [
        "build-logic/build.gradle.kts",
        "build.gradle.kts",
        "tramai-anthropic/build.gradle.kts",
        "tramai-azure-openai/build.gradle.kts",
        "tramai-bedrock/build.gradle.kts",
        "tramai-bom/build.gradle.kts",
        "tramai-core/build.gradle.kts",
        "tramai-dashboard/build.gradle.kts",
        "tramai-deepseek/build.gradle.kts",
        "tramai-embedding/build.gradle.kts",
        "tramai-engine/build.gradle.kts",
        "tramai-gemini/build.gradle.kts",
        "tramai-mcp/build.gradle.kts",
        "tramai-memory-store/build.gradle.kts",
        "tramai-memory/build.gradle.kts",
        "tramai-observability/build.gradle.kts",
        "tramai-ollama/build.gradle.kts",
        "tramai-openai/build.gradle.kts",
        "tramai-orchestration/build.gradle.kts",
        "tramai-persistence-file/build.gradle.kts",
        "tramai-persistence-jdbc/build.gradle.kts",
        "tramai-platform/build.gradle.kts",
        "tramai-rag/build.gradle.kts",
        "tramai-scheduler/build.gradle.kts",
        "tramai-security/build.gradle.kts",
        "tramai-server/build.gradle.kts",
        "tramai-sovereign/build.gradle.kts",
        "tramai-spring-boot-starter-local-provider-openai/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops-actuator/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops-micrometer/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops-observability/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops-rest/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-ops/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-persistence-file/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign-persistence-jdbc/build.gradle.kts",
        "tramai-spring-boot-starter-sovereign/build.gradle.kts",
        "tramai-spring/build.gradle.kts",
        "tramai-standalone/build.gradle.kts",
        "tramai-structured/build.gradle.kts",
        "tramai-testing/build.gradle.kts",
        "tramai-vectorstore-chroma/build.gradle.kts",
        "tramai-vectorstore-pgvector/build.gradle.kts",
        "tramai-vectorstore-spi/build.gradle.kts"
      ],
      "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": [
        "maven"
      ],
      "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": 1,
        "merged_prs": 203,
        "open_issues": 1,
        "closed_ratio": 0,
        "closed_issues": 0,
        "closed_unmerged_prs": 1
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "GionaGranchelli",
          "commits": 633,
          "avatar_url": "https://avatars.githubusercontent.com/u/11965474?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "maintainability-baseline.yml",
        "maintainability-full.yml",
        "publish.yml",
        "sovereign-runtime-release-candidate.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 7,
            "reason": "binaries present in source code",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 3,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "3 out of 3 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/3 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 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": 6,
            "reason": "4 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "b06c9d16267ead14e8e191bb8d50067c3df5b534",
        "ran_at": "2026-07-24T07:33:48Z",
        "aggregate_score": 4.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-24T06:41:07Z",
      "oldest_open_prs": [
        {
          "number": 206,
          "created_at": "2026-07-24T06:47:38Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-24T06:25:02Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 139,
          "created_at": "2026-07-02T21:15:40Z",
          "last_comment_at": "2026-07-06T13:47:22Z",
          "last_comment_author": "GionaGranchelli"
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/GionaGranchelli/tramAI",
    "host": "github.com",
    "name": "tramAI",
    "owner": "GionaGranchelli"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 54,
      "inputs": {
        "security": 40,
        "vitality": 73,
        "community": 42,
        "governance": 31,
        "engineering": 81
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 73,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 73,
            "inputs": {
              "commits_last_year": 633,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 13
            },
            "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": "13/52 weeks with commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 13
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "633 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 633
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "good",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 74,
            "inputs": {
              "releases_count": 1,
              "latest_release_tag": "0.1.0",
              "releases_from_tags": false,
              "days_since_latest_release": 92,
              "mean_days_between_releases": null
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "1 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 92 days ago",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 92
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "cadence unknown (single release)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "release_cadence_unknown",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 42,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 17,
            "inputs": {
              "forks": 0,
              "stars": 12,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "12 stars",
                "points": 16.9,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 12
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 31,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "at_risk",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 38,
            "inputs": {
              "merged_prs": 203,
              "open_issues": 1,
              "closed_issues": 0,
              "issue_closed_ratio": 0,
              "closed_unmerged_prs": 1
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "0% of issues closed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 0
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "203/204 decided PRs merged",
                "points": 38.1,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 203,
                      "decided": 204
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/3 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 50,
            "inputs": {
              "followers": 18,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "GionaGranchelli",
              "public_repos": 14,
              "account_age_days": 4117
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "18 followers of GionaGranchelli",
                "points": 9.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 18,
                      "login": "GionaGranchelli"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "14 public repos, account ~11 yr old",
                "points": 20.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 14
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 11
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 81,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "5 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "3 out of 3 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "ai",
                "kotlin-ai",
                "sovereign-ai",
                "structured-ai",
                "jvm-ai",
                "typed-ai"
              ],
              "has_wiki": true,
              "homepage": "https://tramai.dev",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://tramai.dev",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "6 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "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": 40,
        "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": 40,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 4.1
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "binaries present in source code",
                "points": 5.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection is not maximal on development and all release branches",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "3 out of 3 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/3 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 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": "4 existing vulnerabilities detected",
                "points": 4.5,
                "status": "partial",
                "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": 2
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 72,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                ".github/copilot-instructions.md",
                "AGENTS.md"
              ],
              "agent_instruction_max_bytes": 5513
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": ".github/copilot-instructions.md, AGENTS.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".github/copilot-instructions.md, AGENTS.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 56,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "tramai-dashboard/src/main/frontend/tsconfig.json"
              ],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "build-logic/build.gradle.kts",
                "build.gradle.kts",
                "examples/approval-resume/build.gradle.kts",
                "examples/governed-workflow/build.gradle.kts",
                "examples/kotlin-native-smoke-example/build.gradle.kts",
                "examples/kotlin-springboot-example/build.gradle.kts",
                "examples/sovereign-document-intelligence/build.gradle.kts",
                "examples/sovereign-offline-verification/build.gradle.kts",
                "examples/sovereign-runtime-consumer-smoke/build.gradle.kts",
                "examples/spring-sovereign-starter/build.gradle.kts",
                "examples/support-agent/build.gradle.kts",
                "examples/tool-governance/build.gradle.kts",
                "tramai-anthropic/build.gradle.kts",
                "tramai-azure-openai/build.gradle.kts",
                "tramai-bedrock/build.gradle.kts",
                "tramai-bom/build.gradle.kts",
                "tramai-core/build.gradle.kts",
                "tramai-dashboard/build.gradle.kts",
                "tramai-deepseek/build.gradle.kts",
                "tramai-embedding/build.gradle.kts",
                "tramai-engine/build.gradle.kts",
                "tramai-gemini/build.gradle.kts",
                "tramai-mcp/build.gradle.kts",
                "tramai-memory-store/build.gradle.kts",
                "tramai-memory/build.gradle.kts",
                "tramai-observability/build.gradle.kts",
                "tramai-ollama/build.gradle.kts",
                "tramai-openai/build.gradle.kts",
                "tramai-orchestration/build.gradle.kts",
                "tramai-persistence-file/build.gradle.kts",
                "tramai-persistence-jdbc/build.gradle.kts",
                "tramai-platform/build.gradle.kts",
                "tramai-rag/build.gradle.kts",
                "tramai-scheduler/build.gradle.kts",
                "tramai-security/build.gradle.kts",
                "tramai-server/build.gradle.kts",
                "tramai-sovereign/build.gradle.kts",
                "tramai-spring-boot-starter-local-provider-openai/build.gradle.kts",
                "tramai-spring-boot-starter-sovereign-ops-actuator/build.gradle.kts",
                "tramai-spring-boot-starter-sovereign-ops-micrometer/build.gradle.kts",
                "tramai-spring-boot-starter-sovereign-ops-observability/build.gradle.kts",
                "tramai-spring-boot-starter-sovereign-ops-rest/build.gradle.kts",
                "tramai-spring-boot-starter-sovereign-ops/build.gradle.kts",
                "tramai-spring-boot-starter-sovereign-persistence-file/build.gradle.kts",
                "tramai-spring-boot-starter-sovereign-persistence-jdbc/build.gradle.kts",
                "tramai-spring-boot-starter-sovereign/build.gradle.kts",
                "tramai-spring/build.gradle.kts",
                "tramai-standalone/build.gradle.kts",
                "tramai-structured/build.gradle.kts",
                "tramai-testing/build.gradle.kts",
                "tramai-vectorstore-chroma/build.gradle.kts",
                "tramai-vectorstore-pgvector/build.gradle.kts",
                "tramai-vectorstore-spi/build.gradle.kts"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "build-logic/build.gradle.kts, build.gradle.kts, examples/approval-resume/build.gradle.kts (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "build-logic/build.gradle.kts, build.gradle.kts, examples/approval-resume/build.gradle.kts"
                    }
                  }
                ],
                "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": "tramai-dashboard/src/main/frontend/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tramai-dashboard/src/main/frontend/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "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": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 99,
            "inputs": {
              "primary_language": "Kotlin",
              "largest_source_bytes": 194020,
              "source_files_sampled": 736,
              "oversized_source_files": 8
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Kotlin (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Kotlin"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "8/736 source files over 60KB",
                "points": 54.4,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 736,
                      "oversized": 8
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "moderate",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-24T07:34:05.739833Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/g/GionaGranchelli/tramAI.svg",
  "full_name": "GionaGranchelli/tramAI",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

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

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

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