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

lunguini / flatte

Build TUIs like ordinary Go — one state struct, direct mutation, pure views — the deliberate inverse of Bubble Tea

GoMIT★ 10 星标⑂ 0 复刻始于 2026年6月在 GitHub 上查看 ↗

lunguini/flatte 的健康指数为 100 分中的 50 分,处于「中等」区间。 其得分最高的类别是AI Readiness(76/100),最低的是Sustainability & Governance(36/100)。 最近一次更新在 7 天前。 近期的大部分工作由 1 位贡献者完成。

50
总分 / 100
中等

软件健康指数

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

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

评分画像

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

所有权

lunguini组织
1 关注者8 个公开仓库始于 2026年3月

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

软件包生态系统

注册表软件包版本月下载量版本数最近发布
Gogithub.com/lunguini/flattev0.1.0-110 天前

按类别列示的指标

活力

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

68中等 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 7 天前
4.2/36提交节奏 — 52 周中有 6 周有提交
18/18提交量 — 最近一年 198 次提交
0/10OpenSSF Scorecard:Maintained — project was created within the last 90 days. Please review its contents carefully
所用输入
commits_last_year198
human_commit_share0.99
days_since_last_push7
active_weeks_last_year6

发布纪律

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

社区与采用

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

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

社区健康

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

可持续性与治理

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

36存在风险 · 占总体的 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议题解决 — 没有议题或无数据
12.8/38.3PR 接受 — 已裁定的 PR 中 1/3 已合并
0/15OpenSSF Scorecard:Code-Review — Found 0/28 approved changesets -- score normalized to 0
所用输入
merged_prs1
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs2
已排除计分(无数据或不适用):议题解决。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
2.2/25所有者影响力 — lunguini 有 1 位关注者
7.7/25既往记录 — 8 个公开仓库,账户约 0 年
所用输入
followers1
owner_typeOrganization
is_verified
owner_loginlunguini
public_repos8
account_age_days144
评分方式
25/25已发布且可解析 — go 上有 1 个软件包
35/35发布时效 — 最近一次发布于 10 天前
4/20版本历史 — 1 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagesgithub.com/lunguini/flatte
ecosystemsgo
any_deprecated
min_days_since_publish10

工程质量

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

65中等 · 占总体的 20%

工程实践

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

文档

90优秀
评分方式
30/30README
25/25文档目录
15/15文档 / 主页站点 — https://flatte.lunguini.com
10/10仓库描述
10/10主题标签 — 8 个主题标签
0/10Wiki
所用输入
topicsbubbletea, cli, go, golang, terminal, tui, wasm, framework
has_wiki
homepagehttps://flatte.lunguini.com
has_readme
has_docs_dir
has_description

安全

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

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

安全态势

39存在风险
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
2.2/7.5Branch-Protection — branch protection is not maximal on development and all release branches
0/2.5CI-Tests — 0 out of 1 merged PRs checked by a CI test -- score normalized to 0
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/28 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
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — 无数据
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
6.8/7.5Vulnerabilities — 1 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate3.9
已排除计分(无数据或不适用):packaging, signed_releases。 其余权重已重新归一化。

AI 就绪度

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

76良好 · 占总体的 0%
评分方式
45/45代理指令 — AGENTS.md, CLAUDE.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 99 次人类提交中有 98 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.99
agent_instruction_filesAGENTS.md, CLAUDE.md
agent_instruction_max_bytes10,708
评分方式
12.6/18一条命令的引导启动 — cmd/go.mod, go.mod(工具链约定,无任务运行器)
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — Go(静态类型)
10/10可复现环境 — lockfile
0/10已体现的代理实践 — 最近 100 次提交中没有代理编写的提交
5/8自动化维护 — 已配置依赖自动化,但在抽样提交中未观察到
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfilesgo.sum
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configs
agent_commit_share0
toolchain_manifestscmd/go.mod, go.mod
dependency_bot_commit_share0
评分方式
45/45可类型检查的代码 — Go(静态类型)
54.7/55可控的文件大小 — 采样的 184 个源文件中有 1 个超过 60KB
所用输入
primary_languageGo
largest_source_bytes67,860
source_files_sampled184
oversized_source_files1

关键数据

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

数据采集警告

  • 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 3.9 / 10
3.9综合

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

10Binary-Artifactsno binaries found in the repo
3Branch-Protectionbranch protection is not maximal on development and all release branches
0CI-Tests0 out of 1 merged PRs checked by a CI test -- score normalized to 0
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/28 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
不适用Packagingpackaging workflow not 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
9Vulnerabilities1 existing vulnerabilities detected
直接依赖 13
注册表软件包版本约束清单文件
Gocharm.land/bubbletea/v2v2.0.7cmd/go.mod
Gocharm.land/lipgloss/v2v2.0.4cmd/go.mod
Gogithub.com/charmbracelet/bubbleteav1.3.10cmd/go.mod
Gogithub.com/charmbracelet/ultravioletv0.0.0-20260525132238-948f4557a654cmd/go.mod
Gogithub.com/charmbracelet/x/ansiv0.11.7cmd/go.mod
Gogithub.com/lunguini/flattev0.0.0cmd/go.mod
Gogolang.org/x/termv0.44.0cmd/go.mod
Gocharm.land/lipgloss/v2v2.0.4go.mod
Gogithub.com/charmbracelet/colorprofilev0.4.3go.mod
Gogithub.com/charmbracelet/ultravioletv0.0.0-20260525132238-948f4557a654go.mod
Gogithub.com/charmbracelet/x/ansiv0.11.7go.mod
Gogithub.com/rivo/unisegv0.4.7go.mod
Gogolang.org/x/termv0.44.0go.mod
全部依赖 未采集

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

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [
        "bubbletea",
        "cli",
        "go",
        "golang",
        "terminal",
        "tui",
        "wasm",
        "framework"
      ],
      "is_fork": false,
      "size_kb": 11537,
      "has_wiki": false,
      "homepage": "https://flatte.lunguini.com",
      "languages": {
        "Go": 823814,
        "CSS": 19822,
        "HTML": 12776,
        "Shell": 3020,
        "JavaScript": 6812
      },
      "pushed_at": "2026-07-21T14:35:11Z",
      "created_at": "2026-06-22T01:01:39Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-26T01:44:55Z",
      "description": "Build TUIs like ordinary Go — one state struct, direct mutation, pure views — the deliberate inverse of Bubble Tea",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Go",
      "significant_languages": [
        "Go"
      ]
    },
    "owner": {
      "blog": null,
      "name": "lunguini",
      "type": "Organization",
      "login": "lunguini",
      "company": null,
      "location": null,
      "followers": 1,
      "avatar_url": "https://avatars.githubusercontent.com/u/266040138?v=4",
      "created_at": "2026-03-06T10:13:47Z",
      "is_verified": null,
      "public_repos": 8,
      "account_age_days": 144
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-07-18T10:43:05Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "b031f722ec73eedc08a2751f483938902b0f7bbf",
          "body": "…omponents--flatte\n\nchore(main): release 0.1.0",
          "is_bot": false,
          "headline": "Merge pull request #8 from lunguini/release-please--branches--main--c…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-18T10:42:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "30ea42b559ae4423abe3f0be30092bfcc98d3f25",
          "body": null,
          "is_bot": true,
          "headline": "chore(main): release 0.1.0",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-07-18T10:36:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ececae4b3e196ebc5f467813505d3395b728d2a8",
          "body": "Release-As: 0.1.0",
          "is_bot": false,
          "headline": "chore: release flatte 0.1.0",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-18T10:33:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ed02ef91ea75205ed4be38c2d458f42678fdb8b3",
          "body": "The v0.1.0 tag was seeded on the changelog-seed commit but never released\n(no GitHub release), so release-please treated 0.1.0 as done and proposed\n0.2.0. Reset the manifest to 0.0.0 so the first real release is 0.1.0 (the\nstray tag still needs deleting).\n\nAlso load the landing page at the top: focus the terminal with preventScroll\nso it no longer scrolls into view on load.",
          "is_bot": false,
          "headline": "chore: reset release baseline to 0.0.0 for a 0.1.0 first release",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-18T10:30:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "29ed518d00d4c5894348a1347e3de04fe4b3a13f",
          "body": null,
          "is_bot": false,
          "headline": "fix(flat-landing): hide the pane hint under the leaderboard badge",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-18T10:26:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b0e3e178f133efce40f9fff34cb3633db54f195",
          "body": null,
          "is_bot": false,
          "headline": "feat(flat-landing): point the browser at the live leaderboard Worker",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-18T10:18:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8b3017a67ffa48a2c7363eb56aa35330b528ee91",
          "body": null,
          "is_bot": false,
          "headline": "chore(leaderboard): set the KV namespace id",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-18T10:08:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fb4a746bb1444d2633adf869ea9f6136ace5165a",
          "body": "Add .github/workflows/leaderboard.yml: the runner builds the verifier wasm from\nthe Go source, gates on the zero-dependency Node tests, and deploys with\ncloudflare/wrangler-action. This keeps npm, Node, and Wrangler entirely in CI —\nnothing is installed locally to ship the leaderboard. Rework the README so the\nActions path is primary and local npm is an optional convenience for\n`wrangler dev`.",
          "is_bot": false,
          "headline": "ci(leaderboard): deploy the Worker from GitHub Actions",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-11T02:52:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21896b346cbc10dca80fbabfcd57ed9d5f72b560",
          "body": "Wire the browser build to the leaderboard Worker as a DOM overlay, keeping the\nshared Flatte core pure — the board is browser-only network state and never\nenters State/View. On the Game tab a badge opens the standings; when a game\nends a submit dialog pops with the score, a name field, and the curre\n[…]\ne feature dormant and the demo unchanged. Names are HTML-escaped on\nrender over the server's own sanitize.\n\nAll new browser code is js && wasm-tagged, so the standard build and goldens\nare unaffected.",
          "is_bot": false,
          "headline": "feat(flat-landing): browser Snake leaderboard overlay",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-10T05:19:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8e49c9843469b3415618d53413e02f996375747f",
          "body": "Extract the Snake simulation into a pure, flatte-free cmd/internal/snakesim\npackage so the game and a headless verifier share one source of truth. State\nnow holds an unexported *snakesim.Game, keeping gob persistence to HighScore\nonly; goldens and behavior are byte-identical.\n\nAdd input-log recordin\n[…]\n inside the KV free tier, and edge-caches reads.\nPure logic and the real wasm glue are Node-unit-tested against Go-generated\nfixtures.\n\nBrowser submit/fetch UI and Worker deployment are still pending.",
          "is_bot": false,
          "headline": "feat(leaderboard): verified shared Snake leaderboard backend",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-10T00:25:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "47c723cff006cbc193f391fcc051585ce2d35d90",
          "body": "…lean\n\nSwitch the Pages build from TinyGo to the standard Go toolchain and ship the\nmodule gzip-compressed, inflated in the browser via DecompressionStream. The\nApp tab froze on GitHub Pages with a scheduler deadlock: TinyGo's GC corrupts\nthe asyncify scheduler when a hosted app allocates during a J\n[…]\n from\nthe README thanks and examples.\n\nAlso stop auto-appending a #game/#app fragment on root load: the hash is now\nwritten only when the visitor actually switches tabs, so the root page stays\nat \"/\".",
          "is_bot": false,
          "headline": "feat(flat-landing): standard Go WASM build with gzip, keep root URL c…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-10T00:24:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7ad777451694ce0d466a7da94fff39873be1c9e0",
          "body": null,
          "is_bot": false,
          "headline": "style(flat-landing): vertically center the wordmark against the logo",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-09T06:59:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0fd215893b6374a89e9fe0336c7fba5ca21891ad",
          "body": "The header now shows the Flatte logo alongside the flatte wordmark and\nblinking cursor; the decorative ▚ prefix (.brand-mark::before) that sat\nbefore the wordmark is removed now that the logo carries the mark.",
          "is_bot": false,
          "headline": "style(flat-landing): drop the ▚ brand-mark glyph, keep logo + wordmark",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-09T06:55:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca50973bd4d3131b05088ac7daec126b8e053883",
          "body": "Rebuild flat-landing as an interactive shell: an auto-playing centered\nASCII \"FLATTE\" intro that waits for a keypress, then a split top tab bar —\napps on the left (Game, App), docs on the right (Flatte, Layout, UI). The\nGame and App tabs host the real flat-snake and flat-docker apps, fully\nplayable;\n[…]\no it\n  is never clipped\n- Layout tab demo solves at full content width\n- browser column-axis click drift fixed by measuring the monospace cell\n  width inside the frame element (inherits the real font)",
          "is_bot": false,
          "headline": "feat(flat-landing): interactive tabbed showcase hosting real sample apps",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-09T06:50:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f3d73e4bd34f06ae225a12944e3d47d5abff13e8",
          "body": "A single scripted flat-docker tour read as a mystery — the driving keys\nwere invisible, so the UI changed with no visible cause. Replace it with a\nfast ~12s montage that glimpses six samples (Snake, flat-docker streaming\nlogs, flat-workspace, flat-style, flat-table, flat-progress) so the reader\ngets\n[…]\ntimized 30fps\ndocs/demo.gif (~0.6M). Per-clip recording avoids cross-app quit-key and\nshell-prompt fragility and lets any single clip be re-recorded. Drop the\nnow-superseded cmd/flat-docker/demo.tape.",
          "is_bot": false,
          "headline": "docs(readme): replace demo with a montage sizzle reel",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-07T10:05:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4cc56de4a5b0e6c879d3259c51f36968f0ff7338",
          "body": "Feature cmd/flat-docker at the top of the README: a scripted VHS tour of\nthe Docker-style TUI (list navigation, live logs tab, : command palette\nwith :help/:stream/:filter, and a stop confirm modal). The GIF links\nthrough to the live browser demo.\n\nThe tape lives at cmd/flat-docker/demo.tape and re-records anywhere since\nflat-docker runs on a simulated session. Recorded at 24fps to keep the\ncommitted docs/demo.gif lean (~0.78M).",
          "is_bot": false,
          "headline": "docs(readme): add flat-docker demo GIF recorded with VHS",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-07T09:50:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "406ab7a105ecbdcaccdefc620c092834f70845bd",
          "body": null,
          "is_bot": false,
          "headline": "docs(readme): add live demo badge for flatte.lunguini.com",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-07T09:19:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e3e9bd022931e19688ad021d679936a06ec92f6b",
          "body": "Add a pages workflow that builds the TinyGo WASM artifact and deploys\ncmd/flat-landing/web via actions/deploy-pages. Build artifacts stay\ngitignored; the job produces a fresh .wasm + wasm_exec.js each run.\n\nPin the custom domain flatte.lunguini.com via a committed web/CNAME so it\nsurvives every Actions redeploy, and make the brand link relative (./) so\nit is correct at both a project subpath and the root custom domain.",
          "is_bot": false,
          "headline": "ci(pages): deploy flat-landing to GitHub Pages on a custom domain",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-07T09:17:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d1ebceef20a46f4b53f6188da231e589beaf497b",
          "body": null,
          "is_bot": false,
          "headline": "docs(readme): add Thanks section crediting Charm and dependencies",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-07T09:07:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4f27aa1373a9816c4387504b195da6d38c9b1d6a",
          "body": "Add cmd/flat-landing: one Flatte app core that runs in the terminal and,\nvia a thin js && wasm adapter, live in the browser. It dogfoods tabs,\nTextField search, List catalog, Viewport detail, TabBar rect hit-testing,\nmouse/wheel events, and flatui/layout SolveAndCompose.\n\nPage shell is a terminal-na\n[…]\n keeps concrete padding/font metrics that browserMetrics reads.\n\nTinyGo 0.41.1 build is ~3.18M vs ~5.31M standard-Go fallback; build\nartifacts under web/ are gitignored (build steps in web/README.md).",
          "is_bot": false,
          "headline": "feat(flat-landing): interactive WASM landing sample with redesigned page",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-07T09:05:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1a2e1faf8ff59c2a8a4da6b34139381e8c9639e6",
          "body": "CONTRIBUTING.md states the Conventional Commits rule, the quality bar\n(tests, race, cross-platform vet, gofmt, API snapshot regeneration, the\nreal-terminal gate), the two-module layout, and the hand-maintained\ngolden policy. CHANGELOG.md is seeded with the 0.1.0 release summary;\nrelease-please appends from here. README gains ci/pkg.go.dev/license\nbadges and links the new docs; AGENTS.md points its commit-convention\nrule at the automation and the public guide.",
          "is_bot": false,
          "headline": "docs: contributing guide, changelog seed, README badges",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-06T14:52:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "051b9e53ea94b55a19511b9b20ba376e3b074ae0",
          "body": "GitHub Actions ci workflow runs both modules' tests on ubuntu, macos,\nand windows (race on ubuntu), gofmt, vet on linux plus a GOOS=windows\ncross-vet, and govulncheck. release-please generates CHANGELOG entries\nand version tags from Conventional Commits (manifest seeded at 0.1.0,\nbreaking changes bump the minor pre-1.0). Dependabot watches both go\nmodules and the actions. Golden snapshots are marked -text so a CRLF\ncheckout on Windows runners cannot corrupt byte-compared goldens.",
          "is_bot": false,
          "headline": "ci: test, lint, and vulnerability workflows; release automation",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-06T14:52:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bd225b4a8b6bb53c351ca4d3be4831376ea730b8",
          "body": "The snapshot recorded types, methods, and functions but not struct\nfields, so load-bearing public API like NodeBase.Chrome and the per-side\nPad fields could be renamed without failing the lock. Exported fields\n(including embedded ones) of exported structs are now emitted as\n'field Type.Name' lines; 106 fields join the golden.",
          "is_bot": false,
          "headline": "test: lock exported struct fields in the API snapshot",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T07:49:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25dfed781cd839967f11328b0d553d36ba0ff4c8",
          "body": "PadTop/PadRight/PadBottom/PadLeft add per-side padding on top of the\nsymmetric Pad, inside the border. Extracted on the recorded trigger's\nsecond occurrence (flat-docker's list pane needed top-header/left-only\ninsets via blankSpace spacer scaffolding; flat-workspace's panes baked\nleading spaces for \n[…]\nth render paths now handle per-side insets; flat-docker's\nlistNode adopts the fields and deletes the blankSpace type and its nested\nRow/Col scaffolding with identical rects and byte-identical goldens.",
          "is_bot": false,
          "headline": "feat(layout): per-side padding on NodeBase",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T07:31:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "780dc6105ec3854dbb36727d0af965c3c479e5da",
          "body": "The last pre-engine sample. One layout tree and one SolveAndCompose\nreplace the percentage column split (three Fixed panes in a Row),\nmanual string centering (tabs leaf renders to its solved rect), per-tab\nwidth division, and the cursor-by-string-scanning searchCursor (cursor\nnow derives from rects[\n[…]\n are Bordered\nCols with a borderChrome painter in the focus color. The widget cast\nis unchanged (Tree, Table, Viewport, FocusRing, KeyMap, Progress,\nsearch TextField) and the golden is byte-identical.",
          "is_bot": false,
          "headline": "refactor(flat-workspace): compose the capstone on the layout engine",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T07:25:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1b840e03ea20163ee5cd4bd9d38abf663ab35b18",
          "body": "A git add -A swept a playtest's .flat-game-state.gob into the previous\ncommit; runtime save-state files are user data, not source. Also records\nthe flat-game TTY re-test pass in the tracker.",
          "is_bot": false,
          "headline": "chore: untrack persisted game state; ignore gob state files",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T07:02:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c8a108cc3088758da10ff0a989ceddeae192f35",
          "body": null,
          "is_bot": false,
          "headline": "docs: record flat-game TTY re-test pass",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T07:01:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cd35395a5ec035f3e96862e3f44603c436cafd6e",
          "body": "Two user-playtest findings. The board pane pinned only its width, so its\nborder stretched to the terminal height while the collision grid stayed\n22 rows — the wall looked farther than it was. Pin both axes so the\nborder IS the wall (regression: bottom border directly under the last\ngrid row on a tal\n[…]\nne tick\n(up-then-left while moving right) was silently dropped as a reversal;\nreplace the single buffered turn with a two-deep queue validated against\nthe effective heading, one turn applied per tick.",
          "is_bot": false,
          "headline": "fix(flat-game): pin board pane to the grid; queue fast turns",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T06:52:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8ad6b520057225f1f1ade7037a6f41df58ae6e9f",
          "body": "…l scope\n\nflat-game's dogfooding found that a ticker callback registering a new\nticker (cancel + re-arm an Every from inside a fold) had the registration\nsilently dropped by advance's compact-in-place loop, and that a ticker\ncancelling itself mid-burst kept firing until the advance ended. advance\nno\n[…]\nhey\nfirst fire on the next advance), and stops self-cancelled tickers\nimmediately. Every/Cancel doc comments now state that Cancel only stops\nLatest work and tickers are cancelled through their Scope.",
          "is_bot": false,
          "headline": "fix(flatest): make fakeClock.advance re-entrant; document Every/Cance…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T00:52:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "50a91f943dd6efc0b46b6a27075cde06c83aa4b2",
          "body": "A polished Snake sample exercising the real-time side of Flatte:\na fixed-rate ScopeEvery tick pipeline with named Scope cancellation\n(pause/resume/restart), per-level speed via a tick accumulator, seeded\nRNG in state so food placement is deterministic and goldens are\nbyte-stable, a Chrome-framed boa\n[…]\n-over as styled Overlay nodes, and a\npersistent high score via LoadState/SaveState + OnExit. 20 harness tests\nplus four ANSI-stripped goldens (movement, game over, pause) under the\nflatest fake clock.",
          "is_bot": false,
          "headline": "feat(samples): flat-game — real-time Snake showcase",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T00:49:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2cf7508538ec5b0f5145f6dc6f911a0d429eb8fe",
          "body": null,
          "is_bot": false,
          "headline": "docs: plan for the flat-game real-time showcase sample",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T00:30:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3919b402bb48fcb65e13975184dd6ad8fc59fd01",
          "body": null,
          "is_bot": false,
          "headline": "docs: v0.1.0 release pass — comparison refresh, roadmap complete",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-04T00:26:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b432053454e2da92bbea25531613a9f6ddd7b4b5",
          "body": null,
          "is_bot": false,
          "headline": "docs: record TTY pass for the Chrome/per-row round",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-03T23:53:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a8647bb4bfd2fc8775317498a375cadb2130c2c",
          "body": "…indings",
          "is_bot": false,
          "headline": "docs: sharpen the Chrome/per-row evidence entry with implementation f…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-03T08:21:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e937efe2656ea6b9a1b3cd0906d0bd0b76d52c05",
          "body": "…tree\n\nThe confirm modal becomes a real Overlay:true subtree (modalNode +\nmodalChrome: alert-colored rounded border with the action as a title in\nthe top border rule, colored key hints) composed and cleared by the\nsingle frame walk — the post-solve flatui.Overlay string pass and\nrenderModal are dele\n[…]\nhit rects come from the frame solve and the parallel\nrowRects computation is gone. Screen goldens byte-identical; modal\nvisuals intentionally improved. blankSpace friction noted in the\nevaluation log.",
          "is_bot": false,
          "headline": "refactor(flat-docker): modal as Chrome overlay node; per-row list sub…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-03T08:20:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "469e2b97d5a5cbcc1df6e3c35f79e33ca1993ae6",
          "body": "quick-reference gains a Layout Engine section (Node contract, NodeBase\nfields incl. Chrome, Size kinds and the overlay Grow-fraction rule,\ncontainers/leaves, SolveAndCompose vs Solve, overlays, widget Layout()\nmethods, and the geometry hit-testing pattern with TabBar.WithID/HitTest);\nexamples.md lists flat-layout and flat-docker; README mentions the layout\npackage in the module map.",
          "is_bot": false,
          "headline": "docs: cover the layout engine in the public docs",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-03T07:56:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2807732379ce574aad516891f19c00f7445985b4",
          "body": "A container may now supply its own chrome painter (styled border,\nbackground, title) via NodeBase.Chrome, painted under its children in\nplace of the default Pad/Bordered fill; the layout inset still comes\nfrom Pad/Bordered, so Chrome changes pixels, never geometry. Childless\ncontainers render it through the string path too. First consumer:\nflat-docker pane borders and the confirm modal (next commit).",
          "is_bot": false,
          "headline": "feat(layout): NodeBase.Chrome — custom container decoration",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-03T07:55:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "951240497da1f7a818e95efb4796cfa9db38bfed",
          "body": null,
          "is_bot": false,
          "headline": "docs: plan for docs pass, custom chrome, and flat-docker row structure",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-03T07:50:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e197ddea81f45106cdeeea796862065c357c881",
          "body": "The layout package became load-bearing public API (Node, Solve,\nSolveAndCompose, containers, Rect, Size) but the snapshot only covered\nflatte, flatui, and flatest — layout API changes could slip through\nunlocked. Add it to the scanned package list and regenerate the golden.",
          "is_bot": false,
          "headline": "test: lock flatui/layout in the public API snapshot",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-03T07:40:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c18ba0412e08393adcb3f84d4823ed23069855e8",
          "body": null,
          "is_bot": false,
          "headline": "docs: record flat-docker TTY pass for the d19 fix round",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-03T07:38:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5a34508d36535eb6f7acd20de471db71d33fcb96",
          "body": null,
          "is_bot": false,
          "headline": "docs: record d19 fix outcomes in the review doc",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-02T23:08:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a819af8d42156ebf71576276ec6f8fbf66a63718",
          "body": "…ng zones\n\nTabBar gains WithID (Layout emits ID'd strip + per-tab leaves) and a pure\nHitTest(rects, x, y); the manual-math surface (HandleMouseAt, TotalWidth,\nTabStartX, TabLabelWidth) is removed. flat-docker's header becomes a real\nframe subtree (headerNode + headerRule border leaves) instead of a \n[…]\nmoved flatui.Mark, ZoneScanner.Scan, TabBar.HandleMouseAt,\nTabBar.TotalWidth, TabBar.TabStartX, TabLabelWidth, Rect.Local; flatui.Rect\nfield names changed from Width/Height to W/H (now = layout.Rect).",
          "is_bot": false,
          "headline": "feat(flatui)!: geometry-based hit-testing; one Rect type; retire stri…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-02T22:51:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a9721ef880ddd2127d77e4f79c825c268dd3be8c",
          "body": "…te Grow\n\nCollapse solveNode/composeNode/Row.Render's three distribution loops into a\nsingle walk (Solve = the walk without a paint target; container Render\ndelegates to SolveAndCompose). Overlay pass clears the layer rect and\nrecurses the walk, so overlay descendants get rects and compositor chrome\n[…]\n the\nframe (d19 H2). Zero-weight Grow shares space equally with round-robin\nremainder, and an Auto-axis container whose only claim is a growing child\nreports Grow(1) instead of collapsing (d19 M2+M3).",
          "is_bot": false,
          "headline": "fix(layout): compose overlays through one clamped tree walk; degenera…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-02T22:50:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "006ae065c57caa57661c48b6c69bbf64212ba24c",
          "body": "…ric padding\n\nfillRect previously manufactured full-rect content for the empty case and\npadded with top 0; combined with Lip Gloss v2's minimum total-frame\nWidth/Height semantics, MaxHeight truncated the bottom border of bordered\ncontainers composed through SolveAndCompose (d19 C1), and padded content\npainted one row above its solved rect (d19 C2). Clip content to the inner\nbox before styling, pad symmetrically, and pin exact border/padding\npositions in chrome_test.go.",
          "is_bot": false,
          "headline": "fix(layout): clip content to the inner box so chrome survives; symmet…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-02T14:13:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7920ef1b85ddbfe35ad9266464c28b93ac87998",
          "body": "Collapse the per-frame Solve+Render double walk into a single traversal and delete the free function layout.Render, addressing d18 H1 (engine could not shrink; fixed/content children overflowed and corrupted the frame) and H2 (two independent walks agreeing only via an unenforced 'leaf fills its rec\n[…]\nbugs + d03 evaluation log + d18 H2 updated. QA green both modules: go test, vet darwin+windows, -race on flatui and flat-docker, gofmt, public-API snapshot; user-run TTY pass confirmed before removal.",
          "is_bot": false,
          "headline": "refactor(layout): one-pass compositor; remove layout.Render",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-07-02T06:00:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9b99f309a051464279b4378700a0fe68b876628f",
          "body": null,
          "is_bot": false,
          "headline": "chore: add handoff",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T15:33:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d62bc831f62c3036af3a5a7d72a42e905f9cfd4f",
          "body": null,
          "is_bot": false,
          "headline": "wip",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T15:15:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5250fc29ca6a126c647608a676f4ccd6059da697",
          "body": null,
          "is_bot": false,
          "headline": "feat(flatui): Progress/Viewport/List expose Layout() Node",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T13:22:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8a0d0f7c3a863eadfc81cce755926dfc9c2552ec",
          "body": "…Node",
          "is_bot": false,
          "headline": "refactor(flatui): TabBar exposes Layout() Node, no longer implements …",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T13:21:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7a99affd78e54da15e005692b4805101582a5aee",
          "body": "…delegates",
          "is_bot": false,
          "headline": "refactor(layout): one cell-buffer overlay compositor; flatui.Overlay …",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T13:19:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83a6378dee6ef74bd8190f75d1a0d36563b53a3c",
          "body": null,
          "is_bot": false,
          "headline": "docs: implementation plan for component layout unification",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T13:15:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0da7ce6f79a5cd8d332478e981d48ba70add22bb",
          "body": null,
          "is_bot": false,
          "headline": "docs: spec for component layout unification (Layout() Node model)",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T13:06:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4757c34cea4e62c77a199aada23234b79df14757",
          "body": null,
          "is_bot": false,
          "headline": "docs: refine push-back principle — better, not just simpler",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T06:57:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "63d20c4bd7470e8a49a0d6b9431ceade88570ce2",
          "body": "The Element interface, El(), Content(), ContentBox() are deleted. Node\nnow carries a Layout func(r Rect) Node field directly. Everything is\na Node:\n\n  - Containers: Row(children...), Col(children...)\n  - Text leaves: Text(string)\n  - Widget leaves: Node{Layout: fn} or widget.Node()\n  - Filler: Space\n[…]\nk when there's a simpler way' principle,\ndocumenting the five-iteration arc from Box → ContentBox → Content →\nElement+El → Node.Layout, and the lesson to unify when the third leaf\nconstructor appears.",
          "is_bot": false,
          "headline": "refactor(layout): collapse Element into Node — one type, no interfaces",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T06:55:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "536d6fc631854e665890d9b4b6a9fc53136464ba",
          "body": "TabBar.Render(fill, inactiveFill, barBg) is deleted. Colors are set\nonce via WithColors at init. TabBar implements layout.Element — its\nLayout method returns a Row of tab Content nodes.\n\nThis eliminates the confusing overlap of three APIs (Render returning\nstring, layout.Row used internally, Element\n[…]\nt-docker: colors set once in NewState/newContainersScreen via\n.WithColors(pal.accent, pal.tabBg, pal.bg). All Render calls replaced\nwith El(tabBar) in layout trees. Dead renderTabBar() method deleted.",
          "is_bot": false,
          "headline": "refactor: TabBar is an Element — one uniform API, no Render method",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T06:27:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e34417e647f229996475cee901e694769e3b5ec1",
          "body": "flatui/tabbar.go: TabBar.Render now builds a layout.Row of Content\nnodes and calls layout.Render, replacing manual strings.Builder\nconcatenation. Tab rendering extracted to renderTab helper.\n\nflat-docker: Element types renamed (HeaderView→Header,\nSeparatorView→Separator, FooterView→Footer, ScreenBody→Body).\nShorter, cleaner — no unnecessary View suffix.",
          "is_bot": false,
          "headline": "refactor: TabBar uses layout engine, rename flat-docker Elements",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T06:11:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ea2b35755de1af09682524ab469e7b3d775b5ec",
          "body": "…tring\n\nThe View function now builds a tree of Elements and calls layout.Render.\nNo manual strings.Join, no separate rendering step.\n\nEach frame section is an Element whose Layout returns a subtree:\n- headerView: Row(title, Spacer(), tabs)\n- separatorView: Content(styled line)\n- footerView: Content(\n[…]\nsizes\nfrom its content (padding-aware, no hardcoded heights).\n\nAlso: MeasurePass now skips Element.Layout for non-Auto nodes (Grow/Fixed\nElements don't need measuring), avoiding wasteful Layout calls.",
          "is_bot": false,
          "headline": "refactor(flat-docker): Element-based frame — View returns tree, not s…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T05:51:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a0003b229763b7e3fc64d3daadc057bc9ee3ab04",
          "body": "Elements participate in the layout tree directly. The engine calls\nLayout(w, h) during measure (to discover intrinsic size) and render\n(with solved dimensions). Layout returns a Node subtree — the element\nexpresses its internal structure declaratively, and the engine handles\npositioning and string c\n[…]\ny — an element's\nsubtree can contain more elements.\n\n10 new tests: auto-sizing, adaptive width, subtree layout, nested\nelements, spacer integration, explicit sizing, content leaf, measure\ncorrectness.",
          "is_bot": false,
          "headline": "feat(flatui/layout): Element interface — Layout returns Node, not string",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-28T00:45:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "afc734d86dff31655fee6938d885b6cc89817880",
          "body": "Deleted (replaced by flatui/layout):\n- flatui/compose.go: ComposeHeader + truncateAnsi — replaced by\n  Row(ContentBox, Spacer(), ContentBox) + Render\n- flatui/split_layout.go + test: SplitLayout — replaced by per-screen\n  solver trees\n- flat-docker: paneInnerDims, makeTitledTopBorder, renderTitledPa\n[…]\nt never block the caller from\n  doing something it didn't anticipate.'\n\nAPI snapshot regenerated (ComposeHeader, SplitLayout removed;\nlayout package, SaveState, LoadState, OnExit, Driver.Close added).",
          "is_bot": false,
          "headline": "refactor: delete dead code + add 'healthy abstractions' principle",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-27T23:51:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f7691f03ea7df089abde70ceaa9e0ecaaed93386",
          "body": "Replaces all manual pane geometry and ad-hoc coordinate math with the\nflatui/layout solver. Eliminates flatui.SplitLayout dependency.\n\nGeometry:\n- containersScreen.solveAndSize(): builds Col(Row(list,div0,detail,div1,\n  activity).Grow(1), Box(\"status\").Height(1)), solves, reads dimensions\n- images/v\n[…]\nSIGINT/SIGTERM via App.OnExit\n- Cursor restored after layout (pendingCursor deferred until list sized)\n\nMouse handling updated to use solved rects and dynamic bodyYOffset.\n3 session-state tests added.",
          "is_bot": false,
          "headline": "refactor(flat-docker): use layout solver, ContentBox, state save/reload",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-27T23:51:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4fd62f8c624553401dd2988e73cd42eb6dff23b8",
          "body": "… loop\n\nProves the solver + builder + state save/reload end to end:\n\n- Builds a Col(header, Row(sidebar, content), footer) + modal Layer\n- Renders solved rects as colored blocks in a real terminal\n- m toggles modal (solver Layer, centered), j/k moves cursor\n- State (cursor, modal, terminal size) persists across restart via\n  SaveState/LoadState + SIGINT/SIGTERM trap\n- Header auto-sizes — no hardcoded heights\n\n4 tests: state round-trip, layout solve, modal toggle.",
          "is_bot": false,
          "headline": "feat(cmd/flat-layout): validation harness with colored blocks + state…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-27T23:50:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "313a9a00f64bb85f9aad5dffedfb4c1b8a331991",
          "body": "Save-state + restart-reload mechanism for live edit-and-see loops:\n\n- flatte.SaveState(path, state): gob-encode to file\n- flatte.LoadState(path, default): gob-decode, graceful fallback on\n  missing file, corrupt data, or struct shape change\n- App.OnExit func(*S): fires on every exit path (clean quit\n[…]\nnit flicker on restart\n  - State resets when AppState struct shape changes (decode-error fallback)\n\n9 tests: gob round-trip, missing file, corrupt file, shape change,\nOnExit on quit, OnExit on cancel.",
          "is_bot": false,
          "headline": "feat: state save/reload (SaveState, LoadState, App.OnExit)",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-27T23:50:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e21bffa8298e7189073bfc2ba3f579e5e92e98b2",
          "body": "A flexbox-style layout engine for Flatte. Three layers, each built on\nthe one below:\n\nSolver (node.go, solver.go, layers.go):\n- Stateless: node tree + terminal size in, map[NodeID]Rect out\n- Size constraints: Fixed(n), Grow(weight), Auto (stretch/zero)\n- Containers: Row (horizontal), Col (vertical)\n\n[…]\ning out\n- Eliminates manual strings.Join and width math in apps\n\n46 tests covering: all sizing primitives, deterministic distribution,\nlayers, nesting, slot/inject, auto-sizing, spacer, render output.",
          "is_bot": false,
          "headline": "feat(flatui/layout): stateless solver + builder API + ContentBox/Render",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-27T23:50:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9a15eaa0936259eb7c20a197791fac3342b25495",
          "body": "Deleted: cmd/flat-docker/tab_bar.go and cmd/flat-docker/pane_layout.go.\nReplaced with framework types: flatui.TabBar, flatui.ComposeHeader,\nflatui.SplitLayout. The app now uses the framework versions exclusively.\n\nChanges:\n- State.headerTabs and containersScreen.detailTabs: *tabBar → *flatui.TabBar\n\n[…]\ntly. The app is now a\nconsumer of its own dogfood extractions.\n\n4 pre-existing test failures remain from user's own uncommitted edits\n('containers'→'container' screen name + paneLayout border toggle).",
          "is_bot": false,
          "headline": "refactor(flat-docker): use framework TabBar, ComposeHeader, SplitLayout",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T18:41:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "603808c5ddbbbd99a8f4e21afa42c5c713442285",
          "body": "The dogfood's Task 4 evidence (30-line hand-rolled goroutine for scoped\nlog streaming) is now replaced by flatte.Scope + flatte.ScopeStream.\n\nBefore: startScopedLogs manually created a context.WithCancel, stored\nthe CancelFunc, hand-rolled a goroutine with ticker + select-on-Done +\nNamed update cons\n[…]\nCancelFunc directly.\n\n5 pre-existing test failures remain — from the user's own uncommitted\nedits ('containers' → 'container' screen name + paneLayout border toggle).\nThose are not from this refactor.",
          "is_bot": false,
          "headline": "refactor(flat-docker): use flatte.Scope for scoped logs — 30 LOC → 15",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T18:27:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "68f2495099f50d7f5d22b2c34a9c05755cac22c0",
          "body": "Two major framework extractions in one commit:\n\nflatte.Scope (scope.go) — cancellable async by scope\n- The sharpest finding from the dogfood (Task 4: Every/Stream can't be\n  cancelled by name; only Latest/Cancel can). Scope fixes this by grouping\n  async work under a shared cancellable context.\n- Ne\n[…]\neWidth/PaneCount.\n\nThe dogfood's extraction candidates #1 (layout) and #2 (scoped async) are\nnow framework types. Remaining: flat-docker refactor to use framework\nversions instead of app-local copies.",
          "is_bot": false,
          "headline": "feat: extract flatte.Scope + flatui.SplitLayout from dogfood",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T18:20:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "05c0645dabf2ece76fbf326c2119ff0c29cd85c5",
          "body": "TabBar and ComposeHeader promoted from app-local types in\ncmd/flat-docker/{tab_bar.go} to framework types in flatui/{tabbar.go,\ncompose.go}. The dogfood proved both patterns across multiple locations\n(header tabs + detail tabs for TabBar; app header + pane headers for\nComposeHeader).\n\nflatui/tabbar.\n[…]\nnd composeHeader for now\n(the types are identical in shape; the refactor to use the framework\nversions is a separate commit once flat-docker's tests are green again\nwith the user's own pending edits).",
          "is_bot": false,
          "headline": "feat(flatui): extract TabBar + ComposeHeader from flat-docker dogfood",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T18:13:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "de41c9fe7abd1b88fcd3131b3b2f3df54d213aae",
          "body": "…work fixes from dogfood\n\nThree quick framework improvements found by the flat-docker architecture\ndogfood, all low-risk additions to existing types:\n\n1. KeyPageUp / KeyPageDown added to the closed event set (events.go).\n   Translated from ultraviolet's uv.KeyPgUp/uv.KeyPgDown (and numpad\n   variant\n[…]\non\n   goroutines. Previously apps had to defensively nil-check fx.Context.\n\nPublic API snapshot regenerated (3 new entries: const KeyPageDown, const\nKeyPageUp, method List.Height, method Effects.Ctx).",
          "is_bot": false,
          "headline": "feat: add KeyPageUp/KeyPageDown, List.Height(), Effects.Ctx() — frame…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T18:11:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "347411deadf0bd85cd7ea682137e34a4e525ba34",
          "body": "The flat-docker friction log contains internal architecture findings,\nfile:line evidence, and extraction proposals that shouldn't be visible\nin the public repo. Moved to .docs/d14.md (git-crypt encrypted, opaque\nfilename per project convention). Index updated.\n\nThe public cmd/flat-docker/ no longer contains any internal docs.",
          "is_bot": false,
          "headline": "chore: move FRICTION.md to encrypted .docs/d14.md — not publicly visible",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T18:04:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d7972b75cddfd01f86472ade9375e60f4d17730e",
          "body": ".air.toml moved from project root to cmd/flat-docker/.air.toml. Uses\nroot='../..' so air still watches the full project (flatte framework +\nflat-docker app) but the config and tmp/ output live in the app's own\ndirectory.\n\nUsage:\n  cd cmd/flat-docker\n  air",
          "is_bot": false,
          "headline": "build: move air config into cmd/flat-docker — no root pollution",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T06:54:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d2c45c5759a1b8a5bd122f4dbbb9e20e0f87f6d",
          "body": "Run 'air' from the project root to start flat-docker with live reload.\nAny .go file change (flat-docker code OR flatte framework code) triggers:\nkill → rebuild → restart in <1 second.\n\nConfig: .air.toml at project root\n- Watches all .go files in the project (flatte + flatui + flatest + cmd/*)\n- Excl\n[…]\n-* comparison apps and tmp dir\n- Builds from cmd/ (separate go module)\n- Binary: cmd/tmp/flat-docker\n- 300ms debounce delay to prevent rapid-fire rebuilds\n- 500ms kill delay for clean SIGTERM handling",
          "is_bot": false,
          "headline": "build: add air hot-reload config for development",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T06:43:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4e7d2383ffbf84ac5d7c22c065fc5f348cbc1f76",
          "body": "…ops, solid separator\n\nThree visual cohesion changes per user request:\n\n1. Pane headers now use pal.accent (blue) bg — same color as the app\n   separator. The detail pane's composeHeader (title + tabs) and the\n   activity pane's title row both render on blue bg with dark text.\n   This creates visual\n[…]\nisual is now a sleek, integrated design: dark header →\nsolid blue separator → blue pane headers → content → blue status line\n→ dark footer. The blue elements create visual rhythm without\noverwhelming.",
          "is_bot": false,
          "headline": "feat(flat-docker): sleek integrated look — accent bg headers, flush t…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T06:27:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1ee9089f16420729c25504e268290aa77987d4ab",
          "body": "…eaders\n\nThree visual changes per user request:\n\n1. Removed pane borders (configurable). paneStyle now takes border bool:\n   false = no border + Padding(1,1); true = rounded border + padding.\n   All callers pass false. The border option is there for future use.\n   Since 2*panePadding == paneBorderCo\n[…]\nxy   stats  logs  inspect    activity\n   filter: (all)                                   (no events yet)\n   ●> nginx-proxy     status: running\n\nNo borders, padded, bg-filled headers. Clean and modern.",
          "is_bot": false,
          "headline": "feat(flat-docker): borderless panes with 1-cell padding + bg-filled h…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T06:06:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "72654fa7e37a0625d524928ba29f29f03206a8ec",
          "body": "User feedback: instead of a solid │ column, use a background color\nmatching the pane borders, with a single │ in the vertical center as\na visible grip indicator. Looks much better.\n\nrenderDragDivider(height, dragging) — shared helper used by both\ncontainersScreen.renderDivider and paneLayout.renderD\n[…]\near feedback.\n\npane_layout.go's renderDivider now delegates to the shared helper (was\na duplicate implementation). Both containers screen and images/volumes\nscreens get the same divider look for free.",
          "is_bot": false,
          "headline": "feat(flat-docker): styled dividers — bg-colored column + centered grip",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-26T05:55:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "21435b58e2d6a904c3ce855c6cc8fb836febd7db",
          "body": "…e borders\n\nTwo user-reported issues:\n\n1. Header tab mouse clicks didn't follow the right-aligned tab\n   positions. composeHeader moved tabs to the right, but HandleMouseAt\n   still assumed they started at X=0. Fix: compute the tab strip's\n   right-aligned start X (width - totalTabsWidth) before cal\n[…]\n running               │ ← content\n  ╰────────────────────────────────╯\n\nHeader tab tests updated to compute right-aligned tab positions\n(tabStripStart = width - totalTabsWidth). All three tests pass.",
          "is_bot": false,
          "headline": "fix(flat-docker): header tab mouse zones (right-aligned) + titled pan…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T22:25:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "004720ae8094de403fc6ef54c2c716f55bbaa4de",
          "body": "User wanted: (1) app title in the header alongside the screen tabs,\n(2) container name in the detail pane header alongside the detail tabs,\n(3) no gap between tab items, and (4) a clean way to compose 'title on\none side, tabs on the other' without aggregating them into one component.\n\nNew: composeHe\n[…]\nompose' principle works. title\nand tabBar stay separate; composeHeader is the glue. Same shape as\nflatui.ComposeHeader for the framework — a 10-line helper that every\nheader in every Flatte app needs.",
          "is_bot": false,
          "headline": "feat(flat-docker): composeHeader — title left, tabs right; no gap",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T22:18:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "626162aac655ce1f2b19eca7cbe38a6ed6000030",
          "body": "…emoved\n\nUser requested: (1) remove the empty cell between header tabs (they\nshould touch like real UI tabs), and (2) add mouse support for tabs —\nideally as a reusable tabs component.\n\nNew: cmd/flat-docker/tab_bar.go\n- tabBar type: owns active index, rendering (Powerline tabs that touch\n  directly \n[…]\n\n\nWhat this proves for the framework: tabBar is the concrete shape of\nthe proposed flatui.TabBar — same pattern as paneLayout. Both are\napp-local now; both are extraction candidates for the framework.",
          "is_bot": false,
          "headline": "feat(flat-docker): tabBar component with mouse support + header gap r…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T21:52:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c1bf9dcb0648eaddda462d138d24833307d27871",
          "body": "…resize for free\n\nUser's key architectural insight: 'the panes in images and volumes don't\nnaturally have mouse click or resize support, and this is the kind of\nrepetitive work that could be avoided if components had mouse support\nand resize was built into the layout.'\n\nThis is the extraction the do\n[…]\n tests: images mouse-click, images mouse-wheel, images drag-resize,\nvolumes mouse-click, volumes drag-resize. All pass through the same\npaneLayout code path — zero screen-specific mouse handling code.",
          "is_bot": false,
          "headline": "feat(flat-docker): paneLayout abstraction — images/volumes get mouse+…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T21:43:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "476e8a26defb41334f6ef4db60c67d726818cc4f",
          "body": "…off-by-one\n\nUser-reported: only the left divider (list|detail) was draggable;\nthe right one (detail|activity) missed every click.\n\nRoot cause: div1X in dividerAt had an extra +dividerWidth. Layout is\nlist | div0 | detail | div1 | activity — div1 starts at\nlistPaneWidth + dividerWidth + detailPaneWi\n[…]\n-terminal testing catches and unit\ntests miss when the unit tests share the same wrong formula as the\ncode. The regression test derives the expected X from the layout\nstructure rather than hardcoding.",
          "is_bot": false,
          "headline": "fix(flat-docker): right divider (detail|activity) was un-draggable — …",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T21:20:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7eb05e95dab2ada419b0a60d6b48292e3f981731",
          "body": "User-requested feature: drag the vertical divider between panes to\nresize them live. lazydocker-style column resizing.\n\nDesign:\n- 1-col vertical divider columns (│ char) between list|detail and\n  detail|activity. Normal color is pal.panel (gray); switches to\n  pal.accent (light blue) while being dra\n[…]\nivider 1 shrinks activity, min-width\nclamping, widths persist after terminal resize, list click still\nworks alongside the divider code.\n\nGoldens refreshed — dividers visible as │ between pane borders.",
          "is_bot": false,
          "headline": "feat(flat-docker): mouse-drag resizable columns",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T20:53:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0a40a18690aef23219d632e1def81f9eb2cd885d",
          "body": "User asked whether flat could bundle a font or auto-detect missing\nPowerline glyphs. Honest answer: neither is reliably possible inside\na terminal. The terminal emulator owns font rendering; apps emit code\npoints and have no feedback channel for font coverage.\n\nThis commit implements the honest work\n[…]\ne nice-to-have, not urgent.\n\n7 new tests covering the env-var parsing (default, safe variants,\nexplicit powerline), tip content for both modes, and that the tab\nrenderer respects the chosen glyph set.",
          "is_bot": false,
          "headline": "feat(flat-docker): glyphSet config + FLAT_DOCKER_GLYPHS env var + tip",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T20:45:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "38665c59d6bfaebe277beed97ca14650c98f9095",
          "body": "…eMap\n\nUser clarified the tab design they wanted: Powerline-style diagonal\nslants (U+E0BA / U+E0BC) creating the proper-UI tab look against a\ncolored bar background. Not the slash-style text I implemented.\n\nVisual:\n- New powerlineTab(label, active) helper renders each tab as three\n  styled segments:\n[…]\n Unicode's\nPrivate Use Area (U+E000-U+F8FF). They render correctly in terminals\nwith Powerline or Nerd Fonts installed; standard terminals may show\nboxes. This is the standard tradeoff for this style.",
          "is_bot": false,
          "headline": "feat(flat-docker): Powerline tabs + restore tab clicks via manual Zon…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T20:28:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3378dc83dcf2568c7727348f900a71c8b7dc7bd8",
          "body": "…bug fix\n\nThree changes in one pass, two user-requested visual polish + one\nbug fix that the visual polish surfaced.\n\nVisual polish (user-requested):\n- Header now has a dark background (pal.bg) and a colored heavy-line\n  separator below it (pal.accent on ━ chars). Matches the lazydocker\n  top-bar lo\n[…]\nsserts the keyboard fallback (Right arrow) instead.\nGoldens refreshed — the new visual is distinctly more polished: dark\nheader band, colored separator, slash-style active tabs, touching\npane borders.",
          "is_bot": false,
          "headline": "feat(flat-docker): header restyle + pane gap removed + scroll-border …",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T17:02:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fcfdaf6163173ea869100d0787bafa2848c43634",
          "body": "…is a minimum\n\nUser ran flat-docker in a real terminal (the test harness can't catch\nthis class of bug) and reported: scrolling in stats/logs/inspect tabs\nmade the header (top tabs) and footer (help line) get 'cleaned off'\nthe view. Static chrome vanished while frequently-updated content\n(status lin\n[…]\nentation note, flatui.BoundedStyle helper, renderer-side\nclipping with tracing). This bug validates the entire TTY-verification\nmethodology — no amount of additional unit testing would have caught\nit.",
          "is_bot": false,
          "headline": "fix(flat-docker): TTY-found frame-corruption bug — lipgloss Height() …",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T16:17:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "793f09c5f7c6270909224a1efbc6d9531417fc2b",
          "body": "The last big piece toward the AI-harness direction. Logs viewport now\nbehaves like a real streaming output panel instead of a fixed-width text\ndump.\n\nWrap:\n- Logs switched from SetContent (clip) to SetWrappedContent (soft-wrap).\n  ansi.Hardwrap is ANSI-aware so SGR color sequences and wide runes are\n[…]\n-pause, follow-indicator visibility,\nand the :stream command end-to-end. The TestLogsTabShowsLogLines test\nupdated to assert on parts rather than contiguous substring (the seed\ncontent now wraps too).",
          "is_bot": false,
          "headline": "feat(flat-docker): streaming text panel — wrap, follow-tail, ANSI colors",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T15:59:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4ce66af407e47f8c87c768e4655c5b9d00083376",
          "body": "…ut to activity\n\nAdds a Claude-Code-style command prompt at the bottom of the containers\nscreen (replacing the status line when open). Opens with ':' from list or\ndetail focus (NOT filter — there ':' is text input). Modal-style routing\nin root Handle: modal > command > screen priority. Esc closes; E\n[…]\n it survives across opens. Same pattern as 'side data outlives the\ntransient that produced it' — worth logging as a small architecture\nfinding for the AI-harness case where command state must persist.",
          "is_bot": false,
          "headline": "feat(flat-docker): command bar — ':' prompt with history, routes outp…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T15:38:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "79e921afc4aec6b240e201ccb0e6a26429ce3fb6",
          "body": "Biggest visual transformation per unit of work. Each pane (list, detail,\nactivity in containers; list, detail in images/volumes) is now wrapped in\na rounded-corner border, with the border color shifting to the accent\nwhen the pane is focused. Container status icons get semantic colors\n(green for run\n[…]\nroduction\nmouse handling should also adopt.\n\nGoldens refreshed — the new visual is unmistakably lazydocker-style:\nthree rounded boxes side-by-side, focused one highlighted, content\nproperly contained.",
          "is_bot": false,
          "headline": "feat(flat-docker): pane borders + palette — lazydocker-style boxes",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T15:28:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "88962df519edb1aada67e94a96418f727838de26",
          "body": "… keys\n\nUser reframed the goal: not 'find pain' but 'build something beautiful,\nwith pain as a side effect of genuine craft.' Scroll was the first\nexplicit gap — the underlying flatui.List/Viewport widgets have full\nscroll APIs, but flat-docker exposed none of them visually.\n\nThis pass landed:\n- Vis\n[…]\nthan pain-driven dogfooding — both belong in the\nmethodology going forward.\n\n9 new tests covering scrollbar visibility, wheel routing to list vs\ndetail, f/b/d/u page keys, and the filter-focus gating.",
          "is_bot": false,
          "headline": "feat(flat-docker): scroll affordances — visual scrollbar, wheel, page…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T15:18:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "eb48a93e2077271e78b7be62ad6faee7c914e710",
          "body": "…, avg-MEM status line\n\nThree small user-reported issues after the glamour pass:\n\n1. Tab navigation was [/]/h/l — not discoverable. Added Left/Right arrow\n   handling when detail-focused (filter still owns Left/Right for cursor\n   movement when filter-focused). KeyHints updated to mention arrows.\n\n2\n[…]\n one is wide-but-shallow (layout math);\neverything else is trivial or doesn't need a solution. Recommended\npost-0.1 priority order: ZoneScanner productionization, flatte.Scope,\nthen layout vocabulary.",
          "is_bot": false,
          "headline": "fix(flat-docker): UX polish — arrow-key tabs, highlighted tab styling…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T15:07:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bda487a01a5a49fe27396c9c80536178565016a9",
          "body": "User noted the status line and help footer floated up to wherever body\ncontent ended instead of anchoring to the bottom of the terminal. Two\nissues:\n\n1. chromeRowsBottom counted only the footer (1 row) but the frame\n   layout has separator + footer (2 rows). Body height was one too tall,\n   which wo\n[…]\ns gets bodyContentHeight = height -\nstatusLineRows; images and volumes get bodyContentHeight = height). Same\npattern, same fix.\n\nThree goldens refreshed (the body sections now pad to terminal height).",
          "is_bot": false,
          "headline": "fix(flat-docker): anchor status line + footer to bottom of terminal",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T10:29:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3ed506b9f09526316c86a29216b8caa12c6d1a35",
          "body": "…rototype)\n\nUser asked the right question after the glamour pass broke a mouse test\nwhen layout changed: 'do we need to manually assign mouse zones? can't\nwe build them into the components so they automatically register?' This\nprototype answers it: yes, and the cleanest fit for Flatte's pure-View\nco\n[…]\nayout vocabulary and\nflatte.Scope. The glamour pass breaking a mouse test was the trigger\nthat produced this evidence — itself a validation of the dogfood's\n'build it, hurt, then extract' methodology.",
          "is_bot": false,
          "headline": "feat(flatui): ZoneScanner — output-scanning mouse zones (auto-zones p…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T10:22:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8b803db336b519176570ea066291c7167ffb6a84",
          "body": "…line, sparkline\n\nUser correctly noted the dogfood wasn't glamorous — no anchor-right pane,\nno anchor-bottom status line, no animations. Adding all three exposes\nmore friction than Tasks 5-7 suggested had converged.\n\ncontainersScreen gains:\n- A third anchor-right activity pane showing live events fr\n[…]\nzones (bubblezone-style), which is\n  prototyped next per the user's question about whether components could\n  auto-register zones.\n\n57 tests passing (8 new), race clean, vet clean on darwin + windows.",
          "is_bot": false,
          "headline": "feat(flat-docker): glamour pass — anchor-right activity pane, status …",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T10:04:35Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e0ba93ca901ba9c100d077d5601b82c2eeeaf268",
          "body": "Eighth and final task of the architecture dogfood. Promotes FRICTION.md's\ntask-by-task findings to .docs/d03.md as a synthesis with concrete post-0.1\nextraction proposals in priority order, marks flat-docker as COMPLETE in\nthe status tracker, and adds a 'Final verdict' section to FRICTION.md.\n\nThe d\n[…]\n(Task 4 nil-check\nworkaround), add List.Height() accessor (Task 6 shadow-field workaround).\n\nFull synthesis with proposed API sketches in .docs/d03.md 'Final synthesis\n& extraction proposals' section.",
          "is_bot": false,
          "headline": "docs(flat-docker): final synthesis and post-0.1 extraction proposals",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T09:43:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "17568983ce9990d82bec6b10c23ce9e989b7aaa4",
          "body": "…inearly\n\nSeventh task of the architecture dogfood. imagesScreen and volumesScreen\nreplace their placeholders with full list+detail panes (flatui.List +\nflatui.FocusRing + sample data + keyHints + selected/renderListPane/\nrenderDetailPane). Each is modeled on containersScreen minus tabs/async/\nmouse\n[…]\ne for extraction.\n\nTests cover j/k movement, detail selection, Tab focus cycling, and cross-\nscreen isolation (cursor on one screen preserved while navigating another).\nNew images and volumes goldens.",
          "is_bot": false,
          "headline": "feat(flat-docker): Images + Volumes screens — feature-module scales l…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T09:39:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "14820226d0066a32c72cdf4fcc852672a5efafc6",
          "body": "Sixth task of the architecture dogfood. flatte.WithMouse(MouseModeCellMotion)\nenabled; containersScreen gains a flatui.ZoneMap and a registerMouseZones\nhelper called from layout() that walks the list's visible window registering\none Rect per row at the frame coordinates the row will render at, plus \n[…]\nrectangles. Same pattern as Task 4 where\nViewport.height was unexported. Tests cover click-to-select, click-tab-to-\nswitch, click-outside-zones no-op, mouse-motion no-op, and zone recompute\non resize.",
          "is_bot": false,
          "headline": "feat(flat-docker): mouse via ZoneMap — click rows + tab headers",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T09:34:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e4b439d5f15040b3423d0df092b79a51142a8026",
          "body": "Fifth task of the architecture dogfood. confirmModel struct owns its own\nHandle (y confirm, n/Esc cancel); root Handle adds a one-line modal-first\nguard so all input is captured while a modal is open, but background async\n(Stats Every, Logs streamer) keeps applying through the loop. s/x triggers\nfro\n[…]\ne-module shape extended naturally (confirmModel\nhas its own Handle, root delegates). Tests cover open/confirm/cancel,\ninput capture while open, action application, and overlay rendering over\nthe base.",
          "is_bot": false,
          "headline": "feat(flat-docker): confirm modal for stop/remove",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T09:28:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "30d9f7cbba23f9afa603e61cff5f819cda77a342",
          "body": "…force)\n\nFourth task of the architecture dogfood, and the one that flipped my initial\nreview position. Per the user's 'both — sidestep then force' choice, Stats\nand Logs use deliberately different async patterns so the contrast is\nvisible in code:\n\n- Stats uses the sidestep pattern: one long-lived f\n[…]\nr. Tests cover\nthe sidestepped Stats tick, scoped Logs restart on selection change,\ngoroutine release on cancel, and live-log append routing. Containers\ngolden unchanged (initial state deterministic).",
          "is_bot": false,
          "headline": "feat(flat-docker): async Stats polling + Logs streaming (sidestep vs …",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T09:05:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c46b8bd616753eb31ce11e73450305ec8d5aff03",
          "body": "Third task of the architecture dogfood. The containersScreen detail pane\ngains three tabs via a plain iota (detailTab) + tab field + prevTab/nextTab\nhelpers. Stats tab renders two flatui.Progress bars (CPU/MEM); Logs and\nInspect tabs render flatui.Viewport content. Tab switching via ]/[/h/l when\ndet\n[…]\nr screen, reinforcing the Task 2\nlayout-friction finding. Tests cover tab switching (]/[/h/l), focus gating,\nscroll isolation, tab-bar bracketing, and per-tab content rendering. New\ncontainers golden.",
          "is_bot": false,
          "headline": "feat(flat-docker): detail tabs (Stats/Logs/Inspect) — green-field case",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T06:09:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "322215d45ecf27ddc271f720064f35ee65a7aeb5",
          "body": "…outing\n\nSecond task of the architecture dogfood. containersScreen gains real widget\nstate (flatui.FocusRing cycling filter/list/detail, flatui.TextField filter,\nflatui.List of sample containers, filtered-index slice, static detail pane)\nwithout any change to root Handle or View. Root footer now pul\n[…]\not move list, detail shows selected container, empty-state when no matches,\nand the body-width split between panes. New containers golden; images and\nvolumes goldens refreshed for the new footer text.",
          "is_bot": false,
          "headline": "feat(flat-docker): containers list + filter + static detail + focus r…",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T05:54:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2d278aa892c6afefa0715bfd3238b8548973fda1",
          "body": "…shape\n\nFirst task of a deliberate architecture dogfood: a scripted\nlazydocker-equivalent built to test whether Flatte's API composes pleasantly\nunder a complex multi-pane app. Multi-screen + tabbed detail + async polling\n+ streaming + scoped cancellation + modal + mouse planned across seven\nphases.\n[…]\nery\npain point becomes an app-local helper plus an entry in\ncmd/flat-docker/FRICTION.md; extraction proposals come out of Task 8 with\nsample-driven evidence. Status tracker and evaluation log updated.",
          "is_bot": false,
          "headline": "feat(flat-docker): scaffold architecture dogfood with feature-module …",
          "author_name": "Adrian Lungu",
          "author_login": "adrianlungu",
          "committed_at": "2026-06-25T05:39:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 1,
      "commits_last_year": 198,
      "latest_release_at": "2026-07-18T10:43:05Z",
      "latest_release_tag": "v0.1.0",
      "releases_from_tags": false,
      "days_since_last_push": 7,
      "active_weeks_last_year": 6,
      "days_since_latest_release": 10,
      "mean_days_between_releases": null
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "github.com/lunguini/flatte",
          "exists": true,
          "license": null,
          "keywords": [],
          "ecosystem": "go",
          "matches_repo": true,
          "registry_url": "https://pkg.go.dev/github.com/lunguini/flatte",
          "is_deprecated": false,
          "latest_version": "v0.1.0",
          "repository_url": "https://github.com/lunguini/flatte",
          "versions_count": 1,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": null,
          "latest_published_at": "2026-07-18T10:42:57Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 10
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 10,
      "watchers": 1,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 7
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "cmd/go.mod",
        "go.mod"
      ],
      "largest_source_bytes": 67860,
      "source_files_sampled": 184,
      "oversized_source_files": 1,
      "agent_instruction_files": [
        "AGENTS.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 10708
    },
    "dependencies": {
      "manifests": [
        "cmd/go.mod",
        "go.mod",
        "leaderboard/package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "go",
        "npm"
      ],
      "dependencies": [
        {
          "name": "charm.land/bubbletea/v2",
          "manifest": "cmd/go.mod",
          "ecosystem": "go",
          "version_constraint": "v2.0.7"
        },
        {
          "name": "charm.land/lipgloss/v2",
          "manifest": "cmd/go.mod",
          "ecosystem": "go",
          "version_constraint": "v2.0.4"
        },
        {
          "name": "github.com/charmbracelet/bubbletea",
          "manifest": "cmd/go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.3.10"
        },
        {
          "name": "github.com/charmbracelet/ultraviolet",
          "manifest": "cmd/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.0.0-20260525132238-948f4557a654"
        },
        {
          "name": "github.com/charmbracelet/x/ansi",
          "manifest": "cmd/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.11.7"
        },
        {
          "name": "github.com/lunguini/flatte",
          "manifest": "cmd/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.0.0"
        },
        {
          "name": "golang.org/x/term",
          "manifest": "cmd/go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.44.0"
        },
        {
          "name": "charm.land/lipgloss/v2",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v2.0.4"
        },
        {
          "name": "github.com/charmbracelet/colorprofile",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.4.3"
        },
        {
          "name": "github.com/charmbracelet/ultraviolet",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.0.0-20260525132238-948f4557a654"
        },
        {
          "name": "github.com/charmbracelet/x/ansi",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.11.7"
        },
        {
          "name": "github.com/rivo/uniseg",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.4.7"
        },
        {
          "name": "golang.org/x/term",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.44.0"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 7,
        "merged_prs": 1,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 2
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "adrianlungu",
          "commits": 197,
          "avatar_url": "https://avatars.githubusercontent.com/u/1700129?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "leaderboard.yml",
        "pages.yml",
        "release-please.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 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": 0,
            "reason": "0 out of 1 merged PRs checked by a CI test -- score normalized to 0",
            "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/28 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": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not 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": 9,
            "reason": "1 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "b031f722ec73eedc08a2751f483938902b0f7bbf",
        "ran_at": "2026-07-29T07:34:59Z",
        "aggregate_score": 3.9,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-28T14:34:41Z",
      "oldest_open_prs": [
        {
          "number": 1,
          "created_at": "2026-07-07T09:23:04Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 2,
          "created_at": "2026-07-07T09:23:06Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 3,
          "created_at": "2026-07-07T09:23:07Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 4,
          "created_at": "2026-07-07T09:23:10Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 5,
          "created_at": "2026-07-07T09:23:13Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 9,
          "created_at": "2026-07-14T14:34:50Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 10,
          "created_at": "2026-07-14T14:34:51Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-18T10:42:57Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/lunguini/flatte",
    "host": "github.com",
    "name": "flatte",
    "owner": "lunguini"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 50,
      "inputs": {
        "security": 39,
        "vitality": 68,
        "community": 41,
        "governance": 36,
        "engineering": 65
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 68,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 58,
            "inputs": {
              "commits_last_year": 198,
              "human_commit_share": 0.99,
              "days_since_last_push": 7,
              "active_weeks_last_year": 6
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 7 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 7
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "6/52 weeks with commits",
                "points": 4.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "198 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 198
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "good",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 84,
            "inputs": {
              "releases_count": 1,
              "latest_release_tag": "v0.1.0",
              "releases_from_tags": false,
              "days_since_latest_release": 10,
              "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 10 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 10
                    }
                  }
                ],
                "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": 41,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 16,
            "inputs": {
              "forks": 0,
              "stars": 10,
              "watchers": 1,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "10 stars",
                "points": 15.5,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "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": "1 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 36,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 24,
            "inputs": {
              "merged_prs": 1,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 2
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "1/3 decided PRs merged",
                "points": 12.8,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 1,
                      "decided": 3
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/28 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "followers": 1,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "lunguini",
              "public_repos": 8,
              "account_age_days": 144
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "1 followers of lunguini",
                "points": 2.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 1,
                      "login": "lunguini"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "8 public repos, account ~0 yr old",
                "points": 7.7,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 8
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "good",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "packages": [
                "github.com/lunguini/flatte"
              ],
              "ecosystems": "go",
              "any_deprecated": false,
              "min_days_since_publish": 10
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on go",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "go"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 10 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 10
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "1 published versions",
                "points": 4,
                "status": "partial",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 65,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "at_risk",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 48,
            "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": "4 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "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": "0 out of 1 merged PRs checked by a CI test -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "topics": [
                "bubbletea",
                "cli",
                "go",
                "golang",
                "terminal",
                "tui",
                "wasm",
                "framework"
              ],
              "has_wiki": false,
              "homepage": "https://flatte.lunguini.com",
              "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://flatte.lunguini.com",
                "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": "8 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 8
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 39,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 39,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 3.9
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection 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": "0 out of 1 merged PRs checked by a CI test -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "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/28 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": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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": "1 existing vulnerabilities detected",
                "points": 6.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 76,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.99,
              "agent_instruction_files": [
                "AGENTS.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 10708
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md, CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "98 of 99 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 98,
                      "sampled": 99
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 61,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "cmd/go.mod",
                "go.mod"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "cmd/go.mod, go.mod (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "cmd/go.mod, go.mod"
                    }
                  }
                ],
                "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": "Go (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "dependency automation configured, none observed in the sampled commits",
                "points": 5,
                "status": "partial",
                "details": [
                  {
                    "code": "dependency_bot_config_only",
                    "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": 100,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 67860,
              "source_files_sampled": 184,
              "oversized_source_files": 1
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "1/184 source files over 60KB",
                "points": 54.7,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 184,
                      "oversized": 1
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-29T07:35:06.286558Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/l/lunguini/flatte.svg",
  "full_name": "lunguini/flatte",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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