JSON-Rohbericht maschinenlesbar
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 289,
"has_wiki": true,
"homepage": null,
"languages": {
"Go": 568354
},
"pushed_at": "2026-07-22T08:39:10Z",
"created_at": "2026-05-15T01:46:01Z",
"owner_type": "User",
"updated_at": "2026-07-22T08:40:25Z",
"description": "Pure Go audio metadata library — read & write MP3 (ID3v1/v2.2/v2.3/v2.4), FLAC, MP4/M4A",
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "main",
"license_spdx_raw": "MIT",
"primary_language": "Go",
"significant_languages": [
"Go"
]
},
"owner": {
"blog": "https://cabbagekobe.info/",
"name": null,
"type": "User",
"login": "cabbagekobe",
"company": null,
"location": null,
"followers": 16,
"avatar_url": "https://avatars.githubusercontent.com/u/1041892?v=4",
"created_at": "2011-09-11T05:32:18Z",
"is_verified": null,
"public_repos": 19,
"account_age_days": 5431
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v0.2.1",
"kind": "patch",
"published_at": "2026-07-22T08:39:36Z"
},
{
"tag": "v0.2.0",
"kind": "minor",
"published_at": "2026-07-20T17:22:12Z"
},
{
"tag": "v0.1.5",
"kind": "patch",
"published_at": "2026-07-19T05:35:45Z"
},
{
"tag": "v0.1.4",
"kind": "patch",
"published_at": "2026-05-24T14:35:16Z"
},
{
"tag": "v0.1.3",
"kind": "patch",
"published_at": "2026-05-17T06:20:37Z"
},
{
"tag": "v0.1.2",
"kind": "patch",
"published_at": "2026-05-16T14:31:48Z"
}
],
"recent_commits": [
{
"oid": "9d8830b0e88353c61bc36e6a375ddfe85b18e55c",
"body": "Release v0.2.1",
"is_bot": false,
"headline": "Merge pull request #16 from cabbagekobe/release/v0.2.1",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-22T08:39:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "764eecd158eb409a912286f6f4b2e09e349b9818",
"body": null,
"is_bot": false,
"headline": "Release v0.2.1",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-22T08:37:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6411e1d34336e76d778d020478947aa77328496f",
"body": "fix(mp4): treat all-zero tail as padding, reject mid-stream zero-size box",
"is_bot": false,
"headline": "Merge pull request #15 from cabbagekobe/fix/mp4-zero-tail-padding",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-22T08:36:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ad2fd2be01248a623004ff42b01c290739ab8afd",
"body": "… box\n\niTunes / Apple Music.app leave raw zero padding inside over-declared\nmeta/udta boxes. splitChild now signals end-of-children for any all-zero\ntail, including 1-7 byte tails that previously tripped the truncated-header\ncheck and failed the read. A zero size field followed by non-zero bytes is\nnow a hard error instead of silently ending the walk and dropping the\nsibling boxes that follow.",
"is_bot": false,
"headline": "fix(mp4): treat all-zero tail as padding, reject mid-stream zero-size…",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-22T08:32:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3ccc3acf1de8cf34d42fbb37674364291e9ac0ad",
"body": "Release v0.2.0",
"is_bot": false,
"headline": "Merge pull request #14 from cabbagekobe/release/v0.2.0",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-20T17:21:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d8b0683d3014a2d1b2207a6540f3c9d57ff9195e",
"body": null,
"is_bot": false,
"headline": "Release v0.2.0",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-20T17:19:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "aae87f1742da089bc4520c571a96d1917a7ba917",
"body": "perf(wav,aiff): stream audio chunks instead of buffering in memory",
"is_bot": false,
"headline": "Merge pull request #13 from cabbagekobe/perf/wav-aiff-streaming-io",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-20T17:19:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8ec48cf190b5944f7cde08b9637fa67bdb293d6f",
"body": "WriteFile held the reopened source handle (via defer) across the\nos.Rename that replaces the destination. On Windows, replacing a\nfile that still has an open handle fails with \"Access is denied\",\nbreaking every ReadFile -> WriteFile self-overwrite. The source is\nonly read during encodeTo, so close it right after and before the\nrename.",
"is_bot": false,
"headline": "fix(wav,aiff): close streaming source before rename for Windows",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-20T17:17:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "67205bf297c7c9aab8111728e501773ab3c24de7",
"body": "Read no longer materialises non-metadata chunks (data, SSND,\nfmt , ...): it skips them via Seek and records offset/size, and\nWriteFile streams their bytes from the original source through a\nbufio.Writer. Tag-reading a 317 MB WAV drops from 8.5 s / +317 MB\nheap to 0.4 s with no audio-sized allocation\n[…]\nle + rename path without emitting a corrupt file.\n\nAlso add FuzzReadWAV / FuzzReadAIFF covering the rewritten\nseek-based parsers and the streaming re-encode path, wired into\nthe nightly fuzz workflow.",
"is_bot": false,
"headline": "perf(wav,aiff): stream audio chunks instead of buffering in memory",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-20T17:13:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "38ac1277e96f5f59b3eba0579bc63a060158372b",
"body": "Release v0.1.5",
"is_bot": false,
"headline": "Merge pull request #12 from cabbagekobe/release/v0.1.5",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-19T05:34:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d7c4e153889de7b8a7347b56d0bde87064d42863",
"body": null,
"is_bot": false,
"headline": "Release v0.1.5",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-07-19T05:33:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ecff7a42c10e6e466f642f0a5f50489a3895eed5",
"body": "int(^uint32(0)) overflowed at compile time on 32-bit targets such as ARMv6. Comparing both lengths as uint64 keeps the 4 GiB limit on 64-bit and lets 32-bit builds compile.",
"is_bot": false,
"headline": "fix(aiff,wav): compare encoded size as uint64 for 32-bit builds",
"author_name": "Alex Ballas",
"author_login": "alexballas",
"committed_at": "2026-07-19T05:23:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f549239453a0a1b4530a39ed448676e628b5c1d4",
"body": "fix(mp4): reject oversized box header size to stop fuzz OOM",
"is_bot": false,
"headline": "Merge pull request #9 from cabbagekobe/fix/mp4-fuzz-oversized-box",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-06-04T06:27:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "66e99d896c5cbae3613117f1f5e47fc9c8804cbc",
"body": "readBoxHeader now refuses 32-bit sizes and 64-bit largesize values\nwhose declared total exceeds the remaining file bytes. Without this\nguard, readBoxBody flowed an attacker-controlled BodyLen straight\ninto make([]byte, BodyLen), which let a hostile MP4 force the\nreader to allocate multi-GiB slices a\n[…]\nression tests covering the 32-bit oversize, 64-bit\nlargesize oversize, and the size-at-boundary accept case, plus a\nchecked-in fuzz corpus seed so go test ./mp4/ exercises the\nregression on every run.",
"is_bot": false,
"headline": "fix(mp4): reject oversized box header size to stop fuzz OOM",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-06-04T05:21:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "43657ef54e08303bb5f3bc4950376ccd711cd4e5",
"body": "fix(flac): reject oversized Vorbis Comment count to stop fuzz OOM",
"is_bot": false,
"headline": "Merge pull request #8 from cabbagekobe/fix/flac-fuzz-vorbis-count",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-06-03T11:34:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fade9452e68ed6edbb2e7bc935a4b905d367ddf1",
"body": "parseVorbisComment now validates the declared comment count\nagainst the remaining body size before allocating the result\nslice. A count of 0xFFFFFFFF previously flowed straight into\nmake([]string, 0, count), trying to allocate ~32 GiB and\ncrashing Go fuzz workers, which made the daily FuzzReadFLAC\nG\n[…]\ns three regression tests (count overflow, exact-fit\nboundary, just-over-boundary) and seeds the fuzz corpus with\nthe locally minimized failing input so the same shape stays\ncovered by go test ./flac/.",
"is_bot": false,
"headline": "fix(flac): reject oversized Vorbis Comment count to stop fuzz OOM",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-06-03T11:15:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e00d15e754f1822513881daa638524857c89cd07",
"body": "Release v0.1.4",
"is_bot": false,
"headline": "Merge pull request #7 from cabbagekobe/release/v0.1.4",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-24T14:34:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "022298a8545939c4a306f97d0df62231b46787bc",
"body": null,
"is_bot": false,
"headline": "CHANGELOG: cut v0.1.4 release",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-24T14:33:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c5a8135789593c2e388dd1acb6a3f63a962348e5",
"body": "chore: clean up errcheck/staticcheck/unused lint warnings",
"is_bot": false,
"headline": "Merge pull request #6 from cabbagekobe/fix/lint-cleanup",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-24T14:32:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "80e9491b1710e2979da8f763aa19143b9dfb7335",
"body": "Resolve all 199 outstanding golangci-lint findings (errcheck 197,\nstaticcheck 4, unused 2) without behavior changes to the public API.\n\n- defer Close / cleanup / bare binary.Write etc. get explicit `_ =`\n to signal intentional return-value drop.\n- In-place file writes (mp4 overwriteIlstInPlace / ab\n[…]\n code); mp4\n scanChildren gets //nolint:unused with a forward-use note.\n- gofmt also reformats a few previously-misaligned constant blocks\n (tag.go, flac/picture.go, id3v2 encoding/synchsafe tests).",
"is_bot": false,
"headline": "chore: clean up errcheck/staticcheck/unused lint warnings",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-24T14:31:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a6c3aad2639583fdf0336ecfddaf37e7e2116635",
"body": "feat(mp4): add SetFreeform / FirstFreeform / RemoveFreeform",
"is_bot": false,
"headline": "Merge pull request #5 from cabbagekobe/feature/freeform-mp4-api",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-24T05:31:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ebbd64f92eabda2d3930376fc8278d94da781d48",
"body": "- SetFreeform now no-ops when meanDomain or name is empty, since\n storing such an item would silently fail later at Item.encode.\n- Add table-driven subtest for the guard, a nil-return test for\n FirstFreeform on missing (mean, name), and lock in the\n destructive Remove(\"----\") behavior that the godoc warns about.",
"is_bot": false,
"headline": "mp4: guard SetFreeform empty inputs and expand freeform tests",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-24T05:30:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fdea9521f1791638acbb3e0dbdd3152e478215af",
"body": "The standard Ilst.Set / Remove / First key only on the 4-character ID,\nso passing \"----\" (the freeform sentinel) is unworkable for callers\nthat want to write a single freeform atom: Set removes every freeform\nitem indiscriminately, and the new item it emits has empty mean/name\nboxes which are invali\n[…]\nms\n(iTunNORM, replaygain, …) survive a write and the on-disk layout is\nvalid. Standard 4-character key operations are untouched; the docs\non Set / Remove / First now point callers at the right method.",
"is_bot": false,
"headline": "feat(mp4): add SetFreeform / FirstFreeform / RemoveFreeform",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-23T17:11:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "fad683884822898de2447e4415fb31d9c079c82b",
"body": "CHANGELOG: cut v0.1.3 release",
"is_bot": false,
"headline": "Merge pull request #4 from cabbagekobe/release/v0.1.3",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-17T06:19:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d530d21648dbeb7bf6b15ecf40cbcf17c836226f",
"body": null,
"is_bot": false,
"headline": "CHANGELOG: cut v0.1.3 release",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-17T06:18:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "38379e05f2b9828d0c44a17cbef89112bda0ab93",
"body": "Add ASF/WMA support, Ogg write, and cover art for Ogg/APE",
"is_bot": false,
"headline": "Merge pull request #3 from cabbagekobe/add-asf-and-ogg-write",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-17T05:46:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6f1ec35b0e768f8473bc647a3b500345379a08e9",
"body": "WAV and AIFF chunk readers compared the declared chunk size to\nthe remaining file only after issuing make([]byte, size). A\nmalformed (or hostile) file claiming size = 4 GiB would force a\n4 GiB allocation up front before the subsequent ReadFull failed.\nBoth readers now capture end-of-file at the star\n[…]\n and\nreplaced with a comment explaining why the calculation works\neither way.\n\nRegression tests added: WAV / AIFF reject 4 GiB-claimed chunks\nwithout OOM; APE rejects 4 GiB-claimed item count cleanly.",
"is_bot": false,
"headline": "Harden readers against oversized size / count fields",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-17T02:41:02Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5237b7d3bdfced388b957e7a191ef373cbca2487",
"body": "ASF / WMA (new asf subpackage):\n\n- Content Description Object (Title / Author / Copyright /\n Description / Rating) and Extended Content Description Object\n (any WM/* descriptor with typed Bool / Word / DWord / QWord /\n String / Binary values) read+write.\n- WM/Picture cover art decode + encode.\n- \n[…]\n SetArtist writes to), falling back to\n WM/AlbumArtist only when Author is empty. The previous order\n meant SetArtist(\"X\") could appear to have no effect when\n WM/AlbumArtist was already populated.",
"is_bot": false,
"headline": "Add ASF/WMA support, Ogg write, and cover art for Ogg/APE",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-17T02:26:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b347e27be70e5ffe24da37a47e124e705b16374f",
"body": "Five new format subpackages:\n\n- wav: RIFF/WAVE with LIST/INFO entries and embedded \"id3 \" chunks\n (read+write). RF64 / BW64 rejected explicitly.\n- aiff: AIFF/AIFC with NAME / AUTH / \"(c) \" / ANNO text chunks and\n embedded \"ID3 \" chunks (read+write).\n- ogg: Ogg Vorbis and Ogg Opus com\n[…]\n\ndecode comment packets without duplicating the format.\n\nCLI (print / dump / set / strip / cover) accepts every new\nextension. cover --set embeds APIC into the embedded ID3 chunk\nfor WAV / AIFF / AAC.",
"is_bot": false,
"headline": "Add WAV, AIFF, Ogg, APEv2, and AAC support",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-16T16:30:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c5ce40f3659ddb47296189fdb09b8af6de5ef283",
"body": "CHANGELOG: cut v0.1.2 release",
"is_bot": false,
"headline": "Merge pull request #2 from cabbagekobe/release/v0.1.2",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-16T14:31:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8dabf47a91b5a848220d2349215bd35665ec6a14",
"body": null,
"is_bot": false,
"headline": "CHANGELOG: cut v0.1.2 release",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-16T14:29:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0d4be9b5064965817ed34a7c90ead94c2f01bb6d",
"body": "Detect: return ErrEmptyFile / ErrFileTooSmall for short inputs",
"is_bot": false,
"headline": "Merge pull request #1 from cabbagekobe/detect-empty-file-errors",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-16T12:22:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2e99c88c768b8ff1a2d94d21dc81e8346073f50f",
"body": "Previously Detect returned the generic ErrUnknownFormat for any input\nit could not classify, which made it impossible to distinguish a\ntruncated or zero-byte file from genuinely unsupported content. The\nCLI surfaced these as \"tunetag: unknown format\", which was misleading\nwhen the underlying file wa\n[…]\nBoth new sentinels are refinements of ErrUnknownFormat: errors.Is\nreports true for the old sentinel as well, so existing callers that\nbranch only on ErrUnknownFormat keep working without modification.",
"is_bot": false,
"headline": "Detect: return ErrEmptyFile / ErrFileTooSmall for short inputs",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-16T05:32:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "66a65547e5d9e35f3b954d74caeada432d0e8713",
"body": "最後の文を \"OPERATION OF THE SOFTWARE\" から\n\"USE OR OTHER DEALINGS IN THE SOFTWARE\" に変更。Google の licensecheck\nライブラリ (pkg.go.dev が使用) は前者をマッチ 0%、後者を 98.8% で\nSPDX MIT と認識する。\n\nこれで pkg.go.dev での「Redistributable license」が ☑ になり、\nREADME / ソースコードが正しく表示される。ライセンスの法的意図\n(MIT) は変更なし。\n\nCHANGELOG: v0.1.1 のエントリ追加。",
"is_bot": false,
"headline": "LICENSE: SPDX 標準 MIT に合わせて文末を修正",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-15T02:20:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "02e61c1b0ec6218d4e1d0d301bbc45ac8332aa02",
"body": "flac.rewriteAtomic / id3v2.rewriteWithBody の full-rewrite パスで、\naudio body の io.Copy 後も src の *os.File が開いたままだったため、\nos.Rename(tmpPath, path) が Windows で \"Access is denied\" を返していた。\nUnix ではオープン中ファイルへの rename が成功するため気づかなかった。\n\nsrc を *os.File として受け取り、io.Copy 完了直後 / Rename 直前に\n明示的に Close する。エラーパスでもリーク防止に Close する。\n\nCI: ubuntu/macOS は影響なし。Windows 側で TestWriteFile_FullRewrite\nほか 7 件が落ちていたのが解消する。",
"is_bot": false,
"headline": "Windows: rename 前に元ファイル handle を閉じる",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-15T01:59:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6c50903832a7af1e6e2b1953ff3bc13238ff8dcc",
"body": "毎日 18:00 UTC (03:00 JST) に FuzzReadID3v2 / FuzzReadFLAC /\nFuzzReadMP4 を各 30 秒ずつ並列実行する。failure は GitHub Actions の\n通知メールで届く。workflow_dispatch も有効にしてあるので手動実行も可能。",
"is_bot": false,
"headline": "CI: nightly fuzz workflow を追加",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T17:54:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "140b3a4e3b9f4243c40f2022b4b528f6cf69c3d7",
"body": "- example_test.go: Open / OpenMP3 / OpenFLAC / OpenMP4 / Strip /\n Tag.Pictures の Example* 関数 (godoc に実行可能例として表示)\n- doc.go: Detect → Open → format-specific API の意思決定ツリーと\n サブパッケージ一覧を追加\n- CHANGELOG.md: Keep a Changelog 形式で v0.1.0 の Added セクションを\n 全機能列挙\n- README: 実用パターン (一括スキャン / in-place 再タグ /\n 未対応メタデータの保持) セクション追加",
"is_bot": false,
"headline": "ドキュメント整備: Example* / CHANGELOG / doc.go / README",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T17:53:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cb2e23101dbfdb988de4b33148237c4d2fab131c",
"body": "dump.go の既存パターンに合わせ、main.go の cmdPrint / cmdSet / cmdStrip /\ncmdCover を独立ファイルに切り出し。共有ヘルパは util.go へ。\n\n- main.go: main() + usage() + dispatch のみ (約 60 行)\n- print.go: cmdPrint\n- set.go: cmdSet + setMP3/setFLAC/setMP4 + setFlags\n- strip.go: cmdStrip\n- cover.go: cmdCover\n- util.go: detect / parseSlash / guessMIME",
"is_bot": false,
"headline": "cmd/tunetag: サブコマンドをファイル別に分割",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T17:52:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "05d34856cbc5a076e2d7d80ee52a5360f2dd4564",
"body": "- tunetag.go (443 行) を 3 ファイルに分割\n * tunetag.go: Detect / Open / OpenMP3 / OpenFLAC / OpenMP4\n * strip.go: Strip + stripID3v2/FLAC/MP4\n * wrappers.go: mp3Tag / flacTag / mp4Tag + ヘルパ\n- id3v2/frame_ufid.go の PrivFrame を frame_priv.go に分離\n- internal/testutil → internal/mp4test にリネーム\n (用途が MP4 専用なのを名前で明示)",
"is_bot": false,
"headline": "ファイル分割: ルート tunetag.go / id3v2 frame_ufid.go / internal リネーム",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T17:50:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a9b885c7617cc3da893b99b3522c3d751d4389ae",
"body": "時系列で継ぎ足してきた _edge / _edge2 サフィックス付きテストファイルを\nプロダクションコードのファイル割と一致させた。テスト関数の内容は変更なし、\nファイル配置のみのリファクタリング。\n\n- id3v1: edge_test.go + edge2_test.go を id3v1_test.go に統合\n- id3v2: encoding_edge / frame_edge / synchsafe_edge を各 base に追記マージ。\n edge_test.go は header / frame / synchsafe / write_file / id3v2 に分配\n- \n[…]\nmp4_test.go, atom_test.go, data_test.go, ilst_test.go)\n- ルート: edge_test.go + edge2_test.go を tunetag_test.go に統合し\n 重複していた TestFormat_String / TestPictureType_AllAdvertisedRange を\n 既存 tag_test.go と統合",
"is_bot": false,
"headline": "テストファイルを論理境界で再編成",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T17:47:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "616eef00047337b5050f04bc1dfededcd12c6309",
"body": "- .github/workflows/test.yml: push / pull_request で\n Ubuntu / macOS / Windows × Go 1.23 / 1.24 の 6 マトリクスを並列実行\n (go vet → go build → go test -race -count=1)\n- README: CI バッジと pkg.go.dev バッジを追加、CLI 一覧に dump を記載",
"is_bot": false,
"headline": "GitHub Actions CI と README バッジ / dump 説明を追加",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T16:47:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0976ee494fa43c1da6290bbaa08e58b3d1e84812",
"body": "iTunes が出力する disk atom は reserved(2) + number(2) + total(2) の\n6 バイトで、trkn の 8 バイト (末尾 reserved 2 バイト付き) と異なる。\n従来 TrackNumber() は 8 バイト未満を一律 error にしていたため、\niTunes 由来 m4a ファイルすべてで Disc() が 0/0 を返していた。\n\n最小長を 6 に緩和。offset [2:4] と [4:6] は両形式で同じなので\ntrkn の 8 バイト読みにも影響なし。",
"is_bot": false,
"headline": "MP4: 6 バイトの iTunes 形式 disk atom を受け付ける",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T16:26:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "040f1faaf3f6783a0f9cab3f53610b2a2b9824e0",
"body": "print が共通 Tag interface の 11 項目に絞った概要表示なのに対し、\ndump はライブラリが実際に読み込んでいる全データを型別に表示する。\n\n- ID3v2: 全フレームを TextFrame / UserTextFrame / CommentFrame /\n PictureFrame / PRIV / UFID / GenericFrame など型ごとに詳細出力\n- MP4: 全 ilst item を 4-char キーまたは freeform mean/name で表示、\n data atom の type code (UTF-8 / int / JPEG / PNG / binary) と\n payload プレビュー\n- FLAC: 全 metadata block (STREAMINFO / VORBIS_COMMENT / PICTURE /\n PADDING / 未知 RawBlock) と Vorbis コメント全列挙\n- ID3v1: 7 フィールド + ジャンル名",
"is_bot": false,
"headline": "dump サブコマンドを追加",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T16:25:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a5bd066e62579c6b0eb83ca0b8c150dd23ef6f87",
"body": "- id3v1: Encode / Read\n- id3v2: Encode (V23/V24) / Read / synchsafe / unsync / encodeString\n- flac: Read / encodeMetadata / parseVorbisComment / Get\n- mp4: Read / WriteInPlace / WriteWithFreeAbsorb / scanTopLevel / EncodedMoovBytes\n\nApple M4 Pro 計測値の例:\n- synchsafe encode+decode: 1 ns / 0 allocs\n- 1 MiB APIC を含む ID3v2 Read: 8.1 GB/s\n- 最小 MP4 Read: 11.7 µs / 32 allocs\n- ID3v2 in-place 書き込み: 30-40 µs(syscall 律速)",
"is_bot": false,
"headline": "パッケージ単位のベンチマークを追加",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T15:51:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9b1e554c5372f11e7169422c9b94b1532fdfe3e1",
"body": "- id3v2: synchsafe/unsync 境界、encoding decode/encode、COMM/USLT/UFID/PRIV/APIC/TXXX/WXXX/chooseEncoding 分岐\n- id3v1: byte125 非0 で v1.0 強制、高位バイト保持、長 Title 切詰、Strip 後音声保持\n- flac: parseVorbisComment 各段階の truncation、Picture round-trip と data 長嘘、PADDING 吸収\n- mp4: FourCC、readBoxHeader 境界、makeBEIntData の bit 幅選択、Freeform encode、splitChild\n- tunetag: 各 format の Detect/Open/Strip、mp3Tag の v1 フォールバック、Picture コピー安全性\n- testsound/ ディレクトリを .gitignore に追加",
"is_bot": false,
"headline": "エッジケース テスト大幅拡張(全パッケージ)",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-14T15:08:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4afe28cff3b566097cc53d2fb2f7215ae85a868d",
"body": "各パッケージに新規 edge_test.go を追加し、約 70 件のエッジケース\nを網羅。テスト中に発見した実装バグを併せて修正。\n\n修正したバグ:\n - id3v2/header.go: readHeader が短いファイル (例: \"AUDIO\" 5 byte\n のような ID3v2 magic を持たないもの) で ErrNoTag ではなく\n io.ErrUnexpectedEOF を返していた。「magic 不一致 → ErrNoTag」\n 「magic 一致だが 10 byte 未満 → 'header truncated' エラー」に\n 分岐を整理。O\n[…]\ntch。\n - edge_test.go (root): Detect 空 stream / garbage / 位置回復 /\n \"ftyp\" not at offset 4 / Open 不存在 / Strip 不変 / OpenMP3\n V1+V2 / V1 only / V2 優先。\n\n検証: go vet / go test / go test -race すべて pass。",
"is_bot": false,
"headline": "エッジケース テスト追加と短い入力に関するバグ 2 件修正",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-09T16:05:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d93ba7c3964bd9a85182492abb5a25eb276e8942",
"body": "主な変更:\n - id3v2: Tag.Encode が V22 を受け入れるようにし、PictureFrame に\n PIC body 用の MIME→3-char 変換 (mimeToV22Format) を追加。PRIV や\n TSO2 のように v2.2 等価が無いフレームは encode 時に明示エラー。\n - id3v2: V24 で FlagFooter がセットされたとき \"3DI\" 10-byte trailer\n を出力。padding は仕様通り強制 0、V23 で footer フラグは reject。\n - id3v2: framesEncod\n[…]\npadding 強制 0 確認、V23 での\n footer reject、V24 footer 付き round-trip。\n - mp4/stco_test.go: stco エントリが uint32 上限を超える場合に co64 へ\n 自動昇格し、値が patch されることを確認。\n\n検証: go vet / go test / go test -race すべて pass。",
"is_bot": false,
"headline": "ID3v2.2 write / ID3v2.4 footer / MP4 stco→co64 自動昇格を追加",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-09T06:35:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b70d59eabf570e14827d0f46d32f2a57cbb462e5",
"body": "cgo / WASM を使わない、Go 標準ライブラリのみで MP3 / FLAC / MP4 (M4A)\nのタグを読み書きするライブラリ。\n\n対応:\n - ID3v1 / ID3v1.1: read+write、Winamp 拡張ジャンル含む\n - ID3v2.2: read のみ (canonical 4-char ID へ正規化)\n - ID3v2.3 / ID3v2.4: read+write、in-place / 全書き換え自動切り替え、\n 4 種テキストエンコーディング、APIC / COMM / USLT / TXXX / WXXX /\n UFID / PRIV\n[…]\npenFLAC /\n OpenMP4 / Strip)\n - cmd/tunetag: CLI (print / set / strip / cover)\n - 各サブパッケージ単位の round-trip テスト + 3 形式の fuzz target\n (id3v2 / flac / mp4)\n - go vet / go test / go test -race すべて通過",
"is_bot": false,
"headline": "初回コミット: pure Go の音楽メタデータ ライブラリ tunetag",
"author_name": "cabbagekobe",
"author_login": "cabbagekobe",
"committed_at": "2026-05-09T05:04:53Z",
"body_truncated": true,
"is_coding_agent": false
}
],
"releases_count": 6,
"commits_last_year": 48,
"latest_release_at": "2026-07-22T08:39:36Z",
"latest_release_tag": "v0.2.1",
"releases_from_tags": false,
"days_since_last_push": 3,
"active_weeks_last_year": 6,
"days_since_latest_release": 3,
"mean_days_between_releases": 13.4
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 42,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "github.com/cabbagekobe/tunetag",
"exists": true,
"license": null,
"keywords": [],
"ecosystem": "go",
"matches_repo": true,
"registry_url": "https://pkg.go.dev/github.com/cabbagekobe/tunetag",
"is_deprecated": false,
"latest_version": "v0.2.1",
"repository_url": "https://github.com/cabbagekobe/tunetag",
"versions_count": 8,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-22T08:39:01Z",
"latest_version_yanked": null,
"days_since_latest_publish": 3
}
]
},
"popularity": {
"forks": 1,
"stars": 1,
"watchers": 0,
"fork_history": {
"days": [
{
"date": "2026-07-11",
"count": 1
}
],
"complete": true,
"collected": 1,
"total_forks": 1
},
"star_history": null,
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"go.mod"
],
"largest_source_bytes": 31789,
"source_files_sampled": 92,
"oversized_source_files": 0,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"go.mod"
],
"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"
],
"dependencies": [],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 15,
"open_issues": 0,
"closed_ratio": 1,
"closed_issues": 1,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "cabbagekobe",
"commits": 47,
"avatar_url": "https://avatars.githubusercontent.com/u/1041892?v=4"
},
{
"type": "User",
"login": "alexballas",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/11015965?v=4"
}
],
"contributors_sampled": 2,
"top_contributor_share": 0.979
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"fuzz.yml",
"test.yml"
],
"has_docs_dir": false,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 9,
"reason": "13 out of 14 merged PRs checked by a CI test -- score normalized to 9",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 1/14 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 0,
"reason": "project has 0 contributing companies or organizations -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 10,
"reason": "project is 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": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "9d8830b0e88353c61bc36e6a375ddfe85b18e55c",
"ran_at": "2026-07-26T00:12:45Z",
"aggregate_score": 3.8,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-25T19:13:36Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-07-22T08:39:02Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/cabbagekobe/tunetag",
"host": "github.com",
"name": "tunetag",
"owner": "cabbagekobe"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"security": 38,
"vitality": 73,
"community": 24,
"governance": 57,
"engineering": 60
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 73,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 55,
"inputs": {
"commits_last_year": 48,
"human_commit_share": 1,
"days_since_last_push": 3,
"active_weeks_last_year": 6
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 3 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 3
}
}
],
"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": "48 commits in the last year",
"points": 15.2,
"status": "partial",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 48
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"releases_count": 6,
"latest_release_tag": "v0.2.1",
"releases_from_tags": false,
"days_since_latest_release": 3,
"mean_days_between_releases": 13.4
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "6 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 6
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 3 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 3
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~13.4 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 13.4
}
}
],
"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": "critical",
"name": "Community & Adoption",
"value": 24,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 1,
"stars": 1,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "1 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 1
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "1 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 1
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (MIT)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "MIT"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 57,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 12,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 2,
"top_contributor_share": 0.979
},
"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 98% of commits",
"points": 0.5,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 98
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "2 contributors",
"points": 2.7,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 2
}
}
],
"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": "excellent",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"merged_prs": 15,
"open_issues": 0,
"closed_issues": 1,
"issue_closed_ratio": 1,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "100% of issues closed",
"points": 46.8,
"status": "met",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 100
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "15/15 decided PRs merged",
"points": 38.2,
"status": "met",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 15,
"decided": 15
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 1/14 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 50,
"inputs": {
"followers": 16,
"owner_type": "User",
"is_verified": null,
"owner_login": "cabbagekobe",
"public_repos": 19,
"account_age_days": 5431
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "personal (user) account",
"points": 10,
"status": "partial",
"details": [
{
"code": "owner_personal",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": "not applicable to user accounts",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_applicable_to_user_accounts",
"params": {}
}
],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "16 followers of cabbagekobe",
"points": 8.8,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 16,
"login": "cabbagekobe"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "19 public repos, account ~14 yr old",
"points": 21.5,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 19
}
},
{
"code": "account_age_years",
"params": {
"years": 14
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"github.com/cabbagekobe/tunetag"
],
"ecosystems": "go",
"any_deprecated": false,
"min_days_since_publish": 3
},
"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 3 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 3
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "8 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 8
}
}
],
"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": 60,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 66,
"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": "2 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 2
}
}
],
"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": "13 out of 14 merged PRs checked by a CI test -- score normalized to 9",
"points": 18,
"status": "partial",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": null,
"has_readme": true,
"has_docs_dir": false,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 38,
"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": 38,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 3.8
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "13 out of 14 merged PRs checked by a CI test -- score normalized to 9",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 1/14 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is fuzzed",
"points": 5,
"status": "met",
"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": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"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": "moderate",
"name": "AI Readiness",
"value": 53,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.875,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "42 of 48 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 42,
"sampled": 48
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "at_risk",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 46,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0,
"toolchain_manifests": [
"go.mod"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "go.mod (toolchain convention, no task runner)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "toolchain_convention",
"params": {
"files": "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": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 48",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 48
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Go",
"largest_source_bytes": 31789,
"source_files_sampled": 92,
"oversized_source_files": 0
},
"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": "0/92 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 92,
"oversized": 0
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"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-26T00:12:59.151864Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/c/cabbagekobe/tunetag.svg",
"full_name": "cabbagekobe/tunetag",
"license_state": "standard",
"license_spdx": "MIT"
}