Звіт у форматі JSON машиночитний
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 1216,
"has_wiki": false,
"homepage": null,
"languages": {
"HTML": 4145,
"Python": 525826
},
"pushed_at": "2026-07-25T07:53:38Z",
"created_at": "2026-07-14T11:13:06Z",
"owner_type": "User",
"updated_at": "2026-07-25T07:52:04Z",
"description": "Python-Markdown extension & pdf generation for professional and academic documentation",
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "main",
"license_spdx_raw": "MIT",
"primary_language": "Python",
"significant_languages": [
"Python"
]
},
"owner": {
"blog": null,
"name": "Mark Buckwell",
"type": "User",
"login": "buckwem",
"company": null,
"location": "United Kingdom",
"followers": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/53193258?v=4",
"created_at": "2019-07-22T18:56:17Z",
"is_verified": null,
"public_repos": 3,
"account_age_days": 2559
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "prodockit-v0.10.2",
"kind": "other",
"published_at": "2026-07-25T07:53:50Z"
},
{
"tag": "prodockit-v0.10.1",
"kind": "other",
"published_at": "2026-07-24T22:40:26Z"
},
{
"tag": "prodockit-v0.10.0",
"kind": "other",
"published_at": "2026-07-24T22:00:47Z"
},
{
"tag": "prodockit-v0.9.0",
"kind": "other",
"published_at": "2026-07-24T18:42:19Z"
},
{
"tag": "prodockit-v0.8.1",
"kind": "other",
"published_at": "2026-07-24T08:22:53Z"
},
{
"tag": "prodockit-v0.8.0",
"kind": "other",
"published_at": "2026-07-24T08:00:14Z"
},
{
"tag": "prodockit-v0.7.1",
"kind": "other",
"published_at": "2026-07-24T07:49:52Z"
},
{
"tag": "prodockit-v0.7.0",
"kind": "other",
"published_at": "2026-07-23T23:10:14Z"
},
{
"tag": "prodockit-v0.6.8",
"kind": "other",
"published_at": "2026-07-21T19:24:37Z"
},
{
"tag": "prodockit-v0.6.6",
"kind": "other",
"published_at": "2026-07-21T17:33:17Z"
},
{
"tag": "prodockit-v0.6.5",
"kind": "other",
"published_at": "2026-07-21T09:25:48Z"
},
{
"tag": "prodockit-v0.6.4",
"kind": "other",
"published_at": "2026-07-21T08:47:37Z"
},
{
"tag": "prodockit-v0.6.3",
"kind": "other",
"published_at": "2026-07-20T22:58:07Z"
},
{
"tag": "prodockit-v0.6.2",
"kind": "other",
"published_at": "2026-07-20T20:19:21Z"
},
{
"tag": "prodockit-v0.6.1",
"kind": "other",
"published_at": "2026-07-20T19:34:07Z"
},
{
"tag": "prodockit-v0.6.0",
"kind": "other",
"published_at": "2026-07-20T19:24:38Z"
},
{
"tag": "prodockit-v0.5.0",
"kind": "other",
"published_at": "2026-07-19T10:33:08Z"
},
{
"tag": "prodockit-v0.4.2",
"kind": "other",
"published_at": "2026-07-18T23:29:23Z"
},
{
"tag": "prodockit-v0.4.1",
"kind": "other",
"published_at": "2026-07-18T23:01:47Z"
},
{
"tag": "prodockit-v0.4.0",
"kind": "other",
"published_at": "2026-07-18T21:58:10Z"
},
{
"tag": "prodockit-v0.3.1",
"kind": "other",
"published_at": "2026-07-18T18:19:35Z"
},
{
"tag": "prodockit-v0.3.0",
"kind": "other",
"published_at": "2026-07-18T17:08:47Z"
},
{
"tag": "prodockit-v0.2.0",
"kind": "other",
"published_at": "2026-07-17T23:06:57Z"
},
{
"tag": "prodockit-v0.1.1",
"kind": "other",
"published_at": "2026-07-17T14:52:28Z"
},
{
"tag": "prodockit-v0.1.0",
"kind": "other",
"published_at": "2026-07-17T09:38:29Z"
},
{
"tag": "v0.10.0",
"kind": "minor",
"published_at": "2026-07-15T20:29:38Z"
},
{
"tag": "v0.9.0",
"kind": "minor",
"published_at": "2026-07-15T19:35:21Z"
},
{
"tag": "v0.8.0",
"kind": "minor",
"published_at": "2026-07-15T19:07:57Z"
},
{
"tag": "v0.7.0",
"kind": "minor",
"published_at": "2026-07-15T18:49:20Z"
},
{
"tag": "v0.6.0",
"kind": "minor",
"published_at": "2026-07-14T21:56:29Z"
},
{
"tag": "v0.5.1",
"kind": "patch",
"published_at": "2026-07-14T21:40:10Z"
},
{
"tag": "v0.5.0",
"kind": "minor",
"published_at": "2026-07-14T14:29:13Z"
},
{
"tag": "v0.4.0",
"kind": "minor",
"published_at": "2026-07-14T13:44:16Z"
},
{
"tag": "v0.3.0",
"kind": "minor",
"published_at": "2026-07-14T13:00:28Z"
},
{
"tag": "v0.2.0",
"kind": "minor",
"published_at": "2026-07-14T12:38:47Z"
},
{
"tag": "v0.1.0",
"kind": "minor",
"published_at": "2026-07-14T12:03:00Z"
}
],
"recent_commits": [
{
"oid": "01704d39b624eb13575933cabd2416307555476d",
"body": "Docs-only release: points to Zensical's own site search instead of a\ngeneric browser/Ctrl-F reference - see the changelog for details. No\ncode changes.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.10.2",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-25T07:51:54Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2d6be1a17bb2661b4ded98d1e015101fbed6db04",
"body": "Point to Zensical's own site search instead of browser/Ctrl-F search",
"is_bot": false,
"headline": "Merge pull request #94 from buckwem/update-index-search-reference",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-25T07:49:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7d2a57be8cb3810fce2fe8e0921e13be5141ba04",
"body": "Zensical ships built-in site search (https://zensical.org/docs/setup/search/),\na more accurate and discoverable way to describe how a reader finds a\nterm on the live website than a generic browser Ctrl-F reference.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Point to Zensical's own site search instead of browser/Ctrl-F search",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-25T07:36:17Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e747ccb95357ffaf1b226004b621e3d971f0501e",
"body": "Docs-only release: combines index-term marking and index generation\ninto one docs page, renamed to \"Index (pdf-only)\" - see the changelog\nfor details. No code changes.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.10.1",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T22:38:22Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "82550cf107d25d02a800d1df467108a6969fc25c",
"body": "Combine index-term marking and generation into one docs page, rename to 'Index (pdf-only)'",
"is_bot": false,
"headline": "Merge pull request #93 from buckwem/combine-index-terms-docs",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T22:35:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "398fb995c1d47eeb2b5ec44598a9fc5c53e4507e",
"body": "Now that this page covers the whole feature (marking and generation),\nnot just marking - and to make the PDF-only scope explicit in nav/the\nbrowser tab title. The file path (extensions/index-terms.md) and anchor\nids are unchanged.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Rename 'Index terms' to 'Index (pdf-only)'",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T22:31:46Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "db55270d2477352e240a304280780cc6631c7748",
"body": "prodockit.bibliography's own docs already combine marking (\\citebib{id})\nand generation (\\bibliography) into one page - prodockit.index/\nprodockit.pdf's back-of-book index was split across two pages instead\n(extensions/index-terms.md for marking, pdf.md for generation), even\nthough the marker is use\n[…]\nleft a short pointer in pdf.md's own Configuration/Python API sections -\nmatching how prodockit.bibliography is treated there. No code changes.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Combine index-term marking and index generation into one docs page",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T22:30:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9aaa0c4b7f409cbcf428fa742e1a54789d3002f1",
"body": "… page\"\n\nThis reverts commit ae4358f699639b377fb59f8085bbb9007fe312bf.",
"is_bot": false,
"headline": "Revert \"Combine index-term marking and index generation into one docs…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T22:26:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ae4358f699639b377fb59f8085bbb9007fe312bf",
"body": "prodockit.bibliography's own docs already combine marking (\\citebib{id})\nand generation (\\bibliography) into one page - prodockit.index/\nprodockit.pdf's back-of-book index was split across two pages instead\n(extensions/index-terms.md for marking, pdf.md for generation), even\nthough the marker is use\n[…]\nleft a short pointer in pdf.md's own Configuration/Python API sections -\nmatching how prodockit.bibliography is treated there. No code changes.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Combine index-term marking and index generation into one docs page",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T22:23:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "acde20cfee8c91434be30a0f9ecfcedc155348b2",
"body": "New, backward-compatible feature: prodockit.bibliography's \\bibliography\nmarker now supports generating both a strict References section and a\nbroader Bibliography section - see the changelog for details.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.10.0",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T21:54:52Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "07565557cc0a61db257aa951d620a319dc255d01",
"body": "Add References/Bibliography sections to prodockit.bibliography's \\bibliography marker",
"is_bot": false,
"headline": "Merge pull request #92 from buckwem/generate-references-and-bibliography",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T21:51:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7c3e52c87c5f3f33521e86a839521b12f8613619",
"body": "The \"Comparing the two approaches\" table didn't mention this PR's new\ncapability at all, even though it's a real differentiator - prodockit.citations\nhas no equivalent built-in References/Bibliography split.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add References/Bibliography split to the comparison table",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T21:49:47Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9e07f560dfa21c35a354abba0e25b7fccf922cbf",
"body": "…liography marker\n\n\\bibliography now takes two optional, positional parameters -\n\\bibliography{<file>}{<true|false>} - so a project can generate a strict\nReferences section (cited_only=true) and a broader Bibliography section\n(every entry, including uncited background reading) in the same build,\nfro\n[…]\nr, not a CSL reimplementation), rather than assuming a\nsingle global bibliography page - the common single-file case is\nunaffected.\n\nFixes #89.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add References/Bibliography sections to prodockit.bibliography's \\bib…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T21:16:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0adfbf0da2e899160baace44cfc3b137eb064437",
"body": "Breaking change: copyright/pdf_copyright now render as a real HTML\nfragment in the PDF footer (real links survive) instead of a CSS\ncontent string - see the changelog for details.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.9.0",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T18:40:01Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "cdd3897efd867409670d1f6ef6c5cbddf768750e",
"body": "Give the PDF's copyright footer real Zensical/prodockit links, unlink cover page",
"is_bot": false,
"headline": "Merge pull request #90 from buckwem/adjust-zensical-links",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T18:37:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "40be41e0b6771e0b0769275d45b7de55c1d48707",
"body": "… cover page\n\nFixes #88.\n\n- docs/index.md: the cover page's hero subtitle no longer hyperlinks\n \"Zensical\" - the word stays, the link doesn't.\n- prodockit.pdf.build/css: copyright_text (project.copyright/\n pdf_copyright) is now a real HTML fragment rendered as a real DOM\n element via CSS Paged Me\n[…]\ncted). No formal, versioned public API\nsurface yet for prodockit.pdf (see prodockit-extension#7), so this is\nan acceptable break at this stage.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Give the PDF's copyright footer real Zensical/prodockit links, unlink…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T18:25:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "445b01523899d7d393b4e703473efa2b8606e500",
"body": "Docs-only release: this project's own site and PDF now carry the\n\"Made with Zensical and prodockit\" credit line - see the changelog\nfor details. No library code changed.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.8.1",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T08:20:14Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "319e2f2321fa0ae64d3825814fdbff0124d82075",
"body": "…wn site and PDF\n\nThis project's own docs site and PDF were missing the credit line that\noverrides/partials/copyright.html and pdf_copyright already give a\ndownstream project (e.g. prodockit-template) - added both here too, so\nthis site credits itself the same way a project built with it does.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add the 'Made with Zensical and prodockit' credit to this project's o…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T08:16:59Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d91d96dc41e1d8550a082e699ddd52500c8d547f",
"body": "changelog.md lives in docs/about/, so the link needed ../pdf.md, not\npdf.md - caught by the strict docs build failing in CI after the 0.8.0\nbump.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix broken changelog link to pdf.md's Copyright text section",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T08:03:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9716c3fca0c96f743f5fec8ec15eec9d17903442",
"body": "New opt-in pdf_copyright setting overrides project.copyright for the\nPDF's footer only, plus a white-space: pre-line fix so a \\A forced\nline break in either setting actually renders as a line break - see\nthe changelog for details.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.8.0",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T07:59:35Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ac55a7afc43ed630b8cb47b2e72d9c97e809ea14",
"body": "Add an opt-in pdf_copyright override, PDF-only",
"is_bot": false,
"headline": "Merge pull request #85 from buckwem/add-pdf-copyright-override",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T07:58:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ca9754fa026aa1b009d4981f694bee17050405ef",
"body": "Docs-only release: this project's own docs site now enables every\nprodockit extension, which surfaced and fixed a non-deterministic\nheading-id collision bug in the docs content itself - see the\nchangelog for details. No library code changed.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.7.1",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T07:49:32Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "aca5aa78210be7d9d7325ab986f1bac9cbf59ec5",
"body": "Enable every prodockit extension on this project's own docs site",
"is_bot": false,
"headline": "Merge pull request #87 from buckwem/enable-all-prodockit-extensions",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-24T07:48:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ec8d3bf06e4557b530a86fee1b222e953b944fa4",
"body": "Breaking change: prodockit.bibliography now uses \\citebib{id} instead\nof \\cite{id}, resolving the syntax conflict with prodockit.citations so\nboth can be enabled together - see the changelog for details. Also\nfixes a stale \\cite{id} mention in README.md's bibliography row missed\nby the PR #86 rename.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.7.0",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-23T23:09:53Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "39033d3292a7a7c052b49c4b0d55431f72d78fd4",
"body": "BREAKING: rename prodockit.bibliography's \\cite{id} to \\citebib{id}",
"is_bot": false,
"headline": "Merge pull request #86 from buckwem/rename-bibliography-cite-marker",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-23T23:07:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3722f82060800c53e8f32e7f8f93da2ff97588af",
"body": "zensical.toml now enables prodockit.headings (numbering=\"continuous\"),\nprodockit.refs, prodockit.citations, prodockit.glossary, and\nprodockit.bibliography, alongside the already-enabled prodockit.tables/\nprodockit.index - every extension this project documents is now also\navailable on its own docs s\n[…]\ncross several repeated\nbuilds, confirming the non-determinism is gone) and a real `prodockit\npdf` build (86 pages, no stash-placeholder leaks).\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Enable every prodockit extension on this project's own docs site",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-23T22:19:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e5765e2b44b08825747f3160484b6cf3120126af",
"body": "BREAKING CHANGE: prodockit.bibliography and prodockit.citations both\nused to claim \\cite{id}, so only one could ever be enabled in a build -\nenabling both made their inline patterns (same regex, same priority)\nrace for the same match, with whichever ran first silently winning.\n\nprodockit.bibliograph\n[…]\n\\cite{id} no longer resolves, and a new test confirming\nprodockit.citations and prodockit.bibliography now coexist correctly\nin the same build.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Rename prodockit.bibliography's syntax from \\cite{id} to \\citebib{id}",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-23T21:59:55Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0b1512d308c829913ed8d0543e3d55179a6ee578",
"body": "Adds a \"Copyright text\" section to the PDF generation docs: how\ncopyright feeds both website and PDF by default, how pdf_copyright\noverrides it for the PDF only, the \\A line-break escape (and why it\nneeds a TOML literal string, not a basic one), and a brief pointer to\nthe separate, non-prodockit mechanism for crediting the site on the\nwebsite's own footer (a Zensical custom_dir partials override).\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Document how copyright/pdf_copyright work",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-23T21:38:53Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "46594e19df28957ea34432d849ff145b6234542e",
"body": "project.copyright feeds both the live website's own copyright text and\nthe PDF's running footer - there was no way for a project to show\nsomething different in the PDF only. Added extra.pdf_copyright: unset\nby default (falls back to project.copyright, so every existing\nproject's PDF and website keep\n[…]\n under\nthe default white-space: normal. Added to both the single-sided\n@bottom-left copyright box and the double-sided verso @bottom-right one.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add an opt-in pdf_copyright override, PDF-only",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-23T21:31:44Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9f1af887f9735aa58afee8f9bd7f01e98e41ac67",
"body": "Add cover page marker substitution to build_pdf_from_zensical_config()",
"is_bot": false,
"headline": "Merge pull request #84 from buckwem/upstream-cover-page-markers",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T19:20:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5915160674e3996f48d63b514f0dcf9b88fd3ed3",
"body": "…onflicts)",
"is_bot": false,
"headline": "Merge origin/main into upstream-cover-page-markers (resolve version c…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T19:17:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8d110f345dad24766577282b4fc1db503f13a47d",
"body": "Drop the #only-dark half of a light/dark image pair from PDF output",
"is_bot": false,
"headline": "Merge pull request #83 from buckwem/drop-dark-mode-images-from-pdf",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T19:15:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "27d0dc3f30532f520beed65557636b57e144caa4",
"body": "build_css()'s own docs say copyright_text/site_name \"should already be\nCSS-content-string-safe\" before being passed in - it substitutes both\ndirectly into a content: \"...\" string with no escaping of its own.\nbuild_pdf_from_zensical_config() passed config.get(\"copyright\")/\nconfig.get(\"site_name\") str\n[…]\nker substitution (added earlier this\nbranch) is unaffected - it still uses the raw, unescaped value, since\nit's substituted into HTML, not CSS.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Escape copyright/site_name before passing to build_pdf()'s CSS",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T19:01:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "943c585f9c2da004ad3187a20d32fe5e6bae230f",
"body": "build_pdf_from_zensical_config() only ever read project.extra_css (the\nwebsite's own stylesheet list) - a project wanting a stylesheet meant\n*only* for the PDF (e.g. a rule that would look wrong on the live\nwebsite, like a cover-page-only override) had no way to add one short\nof hardcoding a second \n[…]\nxtra_css rule) - found while migrating\nprodockit-template off its own build_pdf.py, which hardcoded loading a\nsecond \"print.css\" file this way.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add pdf_extra_css for PDF-only stylesheet overrides",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T18:40:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6fa18004bd796b7746e3ee58177aa27a7521f47b",
"body": "Adds {WORDCOUNT}/{REPOURL}/{RELEASE}/{{ site_name }} marker support to\n`prodockit pdf` (build_pdf_from_zensical_config()), so a project no\nlonger needs its own custom Python just to fill in a cover page's word\ncount, repo URL, or release tag - found via prodockit-template, whose\nbuild_pdf.py had shr\n[…]\nonce\ncompiled into the PDF's own temporary work directory - now resolved and\nbase64-embedded, matching how a local <img> reference already was.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add cover page marker substitution to build_pdf_from_zensical_config()",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T18:33:43Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6575a73189bfc503ca8ecb428b99af13424507c4",
"body": "fix_up_page_html() base64-embeds every local <img> into the PDF's HTML\nso it doesn't depend on relative paths resolving from wherever Pandoc\nhappens to run. For a #only-light/#only-dark pair (mkdocs-material/\nZensical's website light/dark toggle convention), to_base64_data_uri()\nalready strips anyth\n[…]\ne source rather than\nonly in the one pipeline that happened to expose it.\n\nAlso updates docs/pdf.md's \"PDF differences vs the website\" section.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Drop the #only-dark half of a light/dark image pair from PDF output",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T18:08:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8b4d4a7d6c044b52f0f1455277bb744baeb8c1ae",
"body": "Bump to 0.6.6",
"is_bot": false,
"headline": "Merge pull request #82 from buckwem/release-0.6.6",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T17:32:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "df7a0907a64c013d047ee68bcada399f942645db",
"body": "Docs-only visual consistency fix (hero graphic/button/index-letter\ncolour) plus the one prodockit.pdf.css constant change - see the\nchangelog for details.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.6.6",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T17:32:19Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "6956cd99c89b22612a79dce6c94c7e916bdcd361",
"body": "Make the hero graphic, PDF download button, and index letter all the same green",
"is_bot": false,
"headline": "Merge pull request #81 from buckwem/green-hero-and-index-color",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T17:28:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "afc9d38555cf9fb973b8dadf3004a554e46effce",
"body": "…ter all the same green\n\n- docs/assets/cover-hero-light.svg previously used a blue palette while\n cover-hero-dark.svg used green - recoloured light to match dark exactly\n (identical path data/stroke-width/opacity, only the stroke colours\n changed), so the hero graphic reads the same regardless of\n[…]\nto #22c55e to match the\n now-green hero graphic a PDF always shows (light variant, regardless of\n a project's own website light/dark toggle).\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Make the light-theme hero graphic, PDF download button, and index let…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T10:11:24Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "273965fa2bc5ca28026718c8a6a3d45fa8e394ac",
"body": "Fold running-header fix into the 0.6.5 changelog entry",
"is_bot": false,
"headline": "Merge pull request #79 from buckwem/changelog-0.6.5-include-header-fix",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T09:16:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3d4b143e077208c555d664a6fa27fbe09deb6895",
"body": "Fix ruff line-length violation in source_bundle.py",
"is_bot": false,
"headline": "Merge pull request #80 from buckwem/fix-ruff-line-length-source-bundle",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T09:16:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9502cd6124751dba1b2dd5d866d401ce31484fcd",
"body": "Wrapped the combined dir/file exclusion check onto multiple lines - it\nwas 103 characters, 3 over ruff's configured 100-character limit, and\nbroke CI on main after PR #78 merged (E501). Verified locally this time:\nruff, mypy, and the full test suite (406/406) all pass.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix ruff line-length violation in source_bundle.py",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T09:15:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e4d3315ad7927b56645d5c340411861bbb52d64b",
"body": "PR #77 (fix source_bundle.pdf's running header naming the wrong file)\nmerged to main alongside the styles/lockfile exclusion work, under the\nsame 0.6.5 version bump, but wasn't mentioned in the changelog entry -\nadd it so the release notes cover everything actually shipping in 0.6.5.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fold the running-header fix (#77) into the 0.6.5 changelog entry",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T09:13:45Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "bd5177632b6fe3567e8dec08dfd6c5550ad51a32",
"body": "…-from-source-bundle\n\nExclude Vale styles and dependency lockfiles from PDF source bundles",
"is_bot": false,
"headline": "Merge pull request #78 from buckwem/exclude-vale-styles-and-lockfiles…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T09:08:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9f135c055f654637523564decbd1f0baead8aa3a",
"body": "…ndary\n\nFix source_bundle.pdf's running header naming the wrong file",
"is_bot": false,
"headline": "Merge pull request #77 from buckwem/fix-source-bundle-header-page-bou…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T09:07:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ad085edb6a7c82f2e4538c7eb123f8929a7febd2",
"body": "Extends the 0.6.4 always-excluded-directory mechanism in\nprodockit.pdf.source_bundle beyond .icons:\n\n- Any directory literally named `styles` - a Vale StylesPath\n (conventionally named this way) holds downloaded rule packs\n (Microsoft/proselint/Readability-style .yml files), typically tracked\n fo\n[…]\ncontent.\n\nNeither exclusion is project-configurable, matching .icons: a project\ncan't reach for the same knob to narrow what a bundle archives.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Exclude Vale styles and dependency lockfiles from PDF source bundles",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T09:02:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "db52ce8137f00b0ec80ab73ff50bc26fe989d2db",
"body": ".file-marker (which sets the string-set: current-file CSS string used\nby the @top-right running header) had no page-break of its own - only\nthe following <pre> did. That let a file's own marker render on the\n*previous* file's last page, right at the tail end just before the\nbreak, so that page's hea\n[…]\nfile long enough to\nspan several pages had its own last page mislabeled with the next\nfile's name; fixed, and covered by a new regression test.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix source_bundle.pdf's running header naming the wrong file",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T09:01:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "692eca62da3ea5ea0cc661e2899604e5c5b3e9d9",
"body": "prodockit.pdf.source_bundle relied entirely on .gitignore to decide\nwhat belongs in source_bundle.pdf, but a project's own custom_icons\ndirectory (pymdownx.emoji's own convention) is typically *tracked* -\nneeded for the site/PDF to build at all - so .gitignore alone can't\nkeep a vendored icon pack o\n[…]\nthe discover_source_files() and\nbuild_source_bundle() level (nested and top-level .icons, and that\n.gitignore has no bearing on it either way).\n\nCo-authored-by: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Always exclude vendored .icons directories from the source bundle (#76)",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T08:46:24Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ea757c23aaabdf026ef4cd0dd50ee56b4734bece",
"body": "…cement\n\nVerify the back-of-book index starts on a recto page under double_sided",
"is_bot": false,
"headline": "Merge pull request #75 from buckwem/test-double-sided-index-recto-pla…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T08:46:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fe128c6845b29f7b5652c5ff1336de00e3e6dc85",
"body": "Checked directly with a real pandoc+weasyprint build (chapter1/chapter2\neach long enough to force page breaks, double_sided=True,\ninclude_index=True): every recto-forced heading, including the\n.unnumbered Index trigger heading, correctly lands on an odd page.\nThis was flagged as an untested interact\n[…]\npandoc+weasyprint\nactually being installed) plus a docstring note on the existing CSS-level\ntest explaining why the exact-string match matters.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Verify the back-of-book index starts on a recto page under double_sided",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-21T08:21:23Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "420380d8819c103d0b73e1dea02ab6fef6906be8",
"body": "Bump to 0.6.3",
"is_bot": false,
"headline": "Merge pull request #74 from buckwem/release-0.6.3",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:57:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5d2004ce2fd6d584bc31216680af2318947a1a4d",
"body": "Bug fixes found by an in-depth test-coverage review of the extensions\nand PDF pipeline test suites - see the changelog for the full list.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.6.3",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:56:51Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c748ed20f0773ffb452ed5bba015ccd804eb85ae",
"body": "Document and test config.py's CWD-relative path resolution",
"is_bot": false,
"headline": "Merge pull request #73 from buckwem/test-config-cwd-relative-paths",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:51:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b399dd7e1d72c8044fb4936ad75960c47a6551b4",
"body": "Add misc PDF pipeline edge-case tests (icons/rotate/html/css)",
"is_bot": false,
"headline": "Merge pull request #72 from buckwem/add-pdf-pipeline-misc-tests",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:50:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1355033eb724642c4914cd4bb213fa6799a26417",
"body": "Add heading_counter_reset() branch tests for zensical_macros.py",
"is_bot": false,
"headline": "Merge pull request #71 from buckwem/add-zensical-macros-branch-tests",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:50:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ffe2c4ad259b133a5288791964433931b61d4bcc",
"body": "Add tables.py nested and multiple-table tests",
"is_bot": false,
"headline": "Merge pull request #70 from buckwem/add-tables-nested-multiple-tests",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:49:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "74bac542e43ff4ec4a30a1d33f0225b6f94c47eb",
"body": "Add malformed-input tests for citations.py/glossary.py",
"is_bot": false,
"headline": "Merge pull request #69 from buckwem/add-malformed-input-tests",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:49:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8ac4e8f0683d2d021b742bd2c3167b2076027683",
"body": "…-tests\n\nAdd direct util.py tests and missing nested cross-page href coverage",
"is_bot": false,
"headline": "Merge pull request #68 from buckwem/add-registry-and-nested-crosspage…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:48:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "56decad56e822479dea7ec162296e457b5eea640",
"body": "Clamp index entry indent level at the deepest CSS rule",
"is_bot": false,
"headline": "Merge pull request #67 from buckwem/fix-pdf-index-depth-cap",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:48:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "940084ec8c7da7fd8ccd85c3dcd36d89f65cda3e",
"body": "Add a timeout to the pandoc/WeasyPrint subprocess call",
"is_bot": false,
"headline": "Merge pull request #66 from buckwem/add-pandoc-subprocess-timeout",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:47:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "21991ad48e78eac084979a778e50710bc64f4f30",
"body": "Escape math_dir/tex2svg_script when embedding them in the Lua filter",
"is_bot": false,
"headline": "Merge pull request #65 from buckwem/fix-lua-path-escaping",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:46:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bd81b3f1149577e449e1aaa6b561731abb694c1f",
"body": "Skip files invalid past is_probably_text's 8 KiB sniff window",
"is_bot": false,
"headline": "Merge pull request #64 from buckwem/fix-source-bundle-unicode-decode",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:46:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d695573ba1fa24e0bd549414c44409abae8bc010",
"body": "Catch OSError in render_mermaid_diagram, not just CalledProcessError",
"is_bot": false,
"headline": "Merge pull request #63 from buckwem/fix-mermaid-oserror",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:45:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "629a1d82bf686cfd9b4093f3390a9cbd9e31a10e",
"body": "Backfill skipped heading levels instead of numbering them 0",
"is_bot": false,
"headline": "Merge pull request #62 from buckwem/fix-headings-numbering-edge-cases",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:44:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c2c0f8d01f0899e2ca96fdd4ef30d59d48c02e2d",
"body": "_find_mmdc_bin/_find_tex2svg_script resolve a relative\npdf_mmdc_bin/pdf_tex2svg_script against the current working directory,\nnot wherever config_path itself lives - fine for the common case of\nrunning `prodockit pdf` from the project root, but an untested footgun\nfor `-f`/`--config-file` pointing a\n[…]\nnged - the\nfix (resolving against config_path's own directory instead) needs a\nfirmer read on backward-compatibility impact before changing it.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Document and test config.py's CWD-relative path resolution",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:33:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "158cce338d31a2d1f0e76a5c7661802dc6302672",
"body": "Pure test-coverage additions, no behavior changes:\n\n- discover_icon_dirs() had zero coverage; build_icon_registry()'s\n documented collision priority (earlier dir wins for derived short-form\n keys, later dir wins for the primary slug key) was unverified.\n- rotate.py's documented \"anything pypdf can\n[…]\nns that copyright_text/site_name must\n already be CSS-string-safe, but nothing demonstrated the actual\n corruption an unescaped quote causes.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add misc PDF pipeline edge-case tests (icons/rotate/html/css)",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:30:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "19e6cbf48f92d407d56e7687c70f796d4efe2a03",
"body": "Only the disabled-config and outside-a-real-build fallback branches\nhad tests - the appendix-letter CSS branch and the \"real build,\nnon-appendix page with n>0\" branch (continuing numbering from earlier\nnav pages) had zero coverage.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add heading_counter_reset() branch tests for zensical_macros.py",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:25:50Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "50c9121f8e72f47c5ca1438406109c68bc15d615",
"body": "No test confirmed a table nested inside an admonition (a realistic\ncombination given how the docs use both together) is still found and\nsized, or that multiple tables in one document - some widthed, some\nnot, with different widths - are each handled independently with no\ncross-contamination.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add tables.py nested and multiple-table tests",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:23:42Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7555c251cebad5f761c46d419c458f0dbf34f1e5",
"body": "citations.py's graceful comma-split handling (empty segments from a\nleading/trailing/double comma), an id-less data-cite-text/data-term\nelement being stripped but not registered, and an empty \\gls{} call\nwere all untested defensive/boundary paths.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add malformed-input tests for citations.py/glossary.py",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:21:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c3d1294b946be1fd1225e4d610e6e3aca9f2b991",
"body": "prodockit.util's IdRegistry/CitationRegistry/GlossaryRegistry/\ncross_page_href had no direct test_util.py at all - only indirect\ncoverage via the extensions that use them. Also, refs.py and glossary.py\nboth lacked the nested-subdirectory cross-page href test that\ncitations.py/bibliography.py each already have.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add direct util.py tests and missing nested cross-page href coverage",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:19:04Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f7b7c4c94b016cbc36e1a5f8c73e608da4edc66f",
"body": "prodockit.pdf.css only defines an indent step up to\ndiv.prodockit-index-level-3 - a 4th nesting level\n(\\index{Parent!Child!Grandchild!GreatGrandchild}) rendered with an\nunstyled prodockit-index-level-4 class, silently landing flush with the\ntop level instead of the deepest available indent. render_index_content()\nnow clamps at MAX_RENDERED_INDEX_LEVEL (3).\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Clamp index entry indent level at the deepest CSS rule",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:16:15Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9b561d92710dade636a5eedcb2329105e718d2e0",
"body": "run_pandoc() had no timeout= on subprocess.run at all, so a hung\npandoc/WeasyPrint invocation (e.g. a pathological CSS layout) blocked\nthe whole build indefinitely with no way to recover. Added a\npandoc_timeout parameter (default 1800s/30 minutes, generous for any\nreal document; pass None to disable) that raises a clear PdfBuildError\non expiry instead.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add a timeout to the pandoc/WeasyPrint subprocess call",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:13:23Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "714a097f7b15316c7fe504497915cca906d3a2e9",
"body": "Both paths were interpolated straight into a double-quoted Lua string\nliteral with no escaping - a path containing a literal \" or an\nunescaped \\ (e.g. a Windows-style path) produced syntactically broken\nLua, only discoverable at real pandoc runtime.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Escape math_dir/tex2svg_script when embedding them in the Lua filter",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:10:51Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c28657c9a9d79dd914c83d31a7584c07f9c15ebd",
"body": "is_probably_text() only sniffs the first 8 KiB of each candidate file,\nbut build_source_bundle() then read the whole file as UTF-8 with no\nerror handling - a file valid in its sniffed prefix but not further in\n(a stray invalid byte, or a multi-byte character split at the boundary)\nraised an uncaught\n[…]\njust skipping that one file the way an outright binary file\nalready is. Also added a test for the (previously untested) empty-\nrepository case.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Skip files invalid past is_probably_text's 8 KiB sniff window",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:08:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4c750b63a1d59aa75f9dc6d99c21783e3b966539",
"body": "A non-executable mmdc_bin (permission bits, or a directory mistakenly\nconfigured as the binary path) makes subprocess.run raise\nPermissionError/OSError directly, not CalledProcessError - this was\npreviously uncaught, contradicting this module's own \"one bad diagram\ncan't fail an entire build\" promise.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Catch OSError in render_mermaid_diagram, not just CalledProcessError",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:05:20Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5b08123e3a38e798ad2409374910a0ef9f5a7688",
"body": "HeadingsTreeprocessor left a shallower level's counter at 0 whenever no\nheading of that level had appeared yet - a document skipping straight\nfrom h1 to h3, starting below h1, or nesting a numbered heading under\nan .unnumbered one all produced a number with a literal \"0\" segment\n(e.g. \"1.0.1\" or \"0.\n[…]\ny such missing shallower level to 1\nbefore incrementing the current one, so the number always reads as a\nsensible implicit first level instead.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Backfill skipped heading levels instead of numbering them 0",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T22:01:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c098eb7eeaf2b13442c229262012f15713b86c35",
"body": "Catch SourceBundleError in the pdf CLI command",
"is_bot": false,
"headline": "Merge pull request #61 from buckwem/fix-cli-source-bundle-error",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T21:55:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf90f5d8b1d1b0ffe2a39740efb2f9d64612c313",
"body": "build_pdf_from_zensical_config() calls build_source_bundle() directly\nwhen pdf_source_bundle is enabled, but SourceBundleError (a plain\nRuntimeError subclass) wasn't in the CLI's caught exception tuple - a\nfailed bundle build (e.g. git missing, or the project root not being a\ngit working tree) crashed with a raw traceback instead of exiting\ncleanly with an Error: message like every other build failure.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Catch SourceBundleError in the pdf CLI command",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T21:54:42Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "efeeaf878c4c1bc154c7af3e6e323cdf2b57b8e3",
"body": "Fix stash-placeholder leak in docs (bump to 0.6.2)",
"is_bot": false,
"headline": "Merge pull request #60 from buckwem/fix-docs-index-syntax-leak",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T20:18:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c8f49d9cdf7c42ec3229ad3c25f110c3c3c48af8",
"body": "… guard\n\nInvestigated further and found the real trigger: pymdownx.inlinehilite\n(this project's own zensical.toml, and almost certainly any real Zensical\nproject's) replaces Python-Markdown's plain 'backtick' inline pattern\nwith its own - same priority and registry name, but a different\nimplementati\n[…]\nut the placeholder's name\nas an example, indistinguishable from a real leak once rendered - reworded\nto describe it without the literal string.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add regression tests for the stash-placeholder leak, plus a repo-wide…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T20:17:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d731221c8ec474d3c6889a52ee2ed9fa4bd6b52e",
"body": "Fixed a real bug found by checking the live site after 0.6.1: several\nspots in docs/extensions/index-terms.md, docs/pdf.md, and this project's\nown changelog tried to show the code-styled \\index{} syntax as literal\nexample text using inline backticks around a hierarchical, code-styled\npath (e.g. `\\in\n[…]\nk or reworded to avoid\nthe literal example entirely. Verified end-to-end: rebuilt the site\nlocally and confirmed no placeholder leaks anywhere.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.6.2",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T20:06:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a2b47468e591a87256aac95f2ac56a893641ea66",
"body": "Add prodockit.index to README/PyPI metadata (bump to 0.6.1)",
"is_bot": false,
"headline": "Merge pull request #59 from buckwem/readme-add-index-extension",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T19:33:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0b7eb00b4e82cd681a756e1b25476a6f2f7aa582",
"body": "Add prodockit.index (new in 0.6.0) to README.md, pyproject.toml's own\ndescription (PyPI's summary line), and __init__.py's module docstring -\nall three had the same gap, matching the exact oversight this project\nalready fixed once before for prodockit.tables/prodockit.bibliography\n(see the 0.3.1 changelog entry).\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.6.1",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T19:31:05Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b97bef823f884b4920898f9ae4149d5c38778ee2",
"body": "Bump to 0.6.0",
"is_bot": false,
"headline": "Merge pull request #58 from buckwem/bump-0.6.0",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T19:23:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9a902873b6d92f0ac930f428dfc363fbb058fbda",
"body": "New back-of-book index (\\index{Term}, #55/#57): hierarchical sub-entries,\ncode-styled terms, and the pdf_include_index/pdf_index_title two-pass PDF\nbuild behind it - see the changelog for the full feature list.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Bump to 0.6.0",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T19:22:57Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e20632fd3a7e0cd95eba7306e5d43ccd20c173f7",
"body": "Add a back-of-book style Index, PDF-only",
"is_bot": false,
"headline": "Merge pull request #57 from buckwem/back-of-book-index-55",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T19:18:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ee0d8f51c40dffae774da565520652cc1452f562",
"body": "While reviewing test coverage, found that \\index{`Git`!commit} (an\nunsupported combination - code-styling isn't meant to work on anything\nbut the last segment) didn't just fail to work, it actively corrupted\nthe output: INDEX_CODE_RE only matched a backtick pair immediately before\nthe closing }, so \n[…]\non-\nprefixed terms that share a sort key but stay separate entries, and a\npurely-punctuation term exercising _sort_key()'s own fallback branch.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Fix a real bug: code-styling a non-last segment corrupted the term",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T19:17:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f6967386c09ecac4b02d12cad007b43db0490be9",
"body": "- test_term_as_a_raw_html_link_preserves_target_blank: confirms the\n documented raw <a target=\"_blank\"> workaround (for when attr_list\n can't combine cleanly with a linked term) keeps the attribute intact.\n- test_term_works_inside_an_admonition /\n test_mark_index_terms_finds_a_term_nested_inside_\n[…]\nwn span lookup already\n work correctly regardless of the surrounding <div class=\"admonition\">\n wrapper, checked directly rather than assumed.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add tests for target=\"_blank\" preservation and admonition-nested terms",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T19:08:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9d24c8a69dc2ea9c34853d18b53dd1255568a6c2",
"body": "Letter headings (A, B, C...) now use #1e3a8a - the innermost, most\nsaturated ring of prodockit-template/prodockit-userguide's own shared\ncover page hero graphic (docs/assets/cover-hero-light.svg) - replacing\nthe arbitrary brick red picked earlier. Confirmed directly against a\nreal rendered PDF that \n[…]\nhe attribute's own braces confuse \\index{}'s regex if\nplaced inside) - a raw inline <a target=\"_blank\"> tag is the workaround,\nalso documented.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Index letter headers match the hero graphic; document linked terms",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T19:02:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "35e2e65233fdc07aede541499891670b9f7be078",
"body": "Backticks around a term's last segment - \\index{`git commit`}, or\ncombined with hierarchy, \\index{Git!`git commit`} - mark it as a\ncommand/code term: it displays inline in a real <code> element, and the\ngenerated index entry renders the same way, picking up whatever code {}\nstyling a project already\n[…]\ns, chmod, grep) -\nconfirmed both the built PDF and the live website render each one\ncode-styled, in the prose and in the generated index alike.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Support code-styled index terms: \\index{`Term`}",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T18:50:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8adb698a5d6eaf82ed7a9591e7540975c54c7363",
"body": "Full back-of-book index spec: \\index{Parent!Child!Grandchild} (matching\nLaTeX makeidx's own long-established convention) nests up to three levels\ndeep, each level indented a fixed 12pt step; consecutive pages collapse\ninto an en-dash range (\"67–70\") rather than listing every page; and a\nterm alphabe\n[…]\netic build exercising all of the above\n(hierarchy, ranges, punctuation sorting) plus a real rebuild of\nprodockit-userguide's own 18-term index.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add hierarchical sub-entries and page-range formatting to the index",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T17:26:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "da2114699ca567e93705b2e4c24e51b8e20ed3ac",
"body": "Matches a traditional printed book's own index layout: a bold letter\nheading (A, B, C, ...) per group, entries below as \"Term, page, page\"\n(comma-separated, not colon), the whole thing in two columns (WeasyPrint's\nCSS Multi-column support, confirmed directly to paginate correctly).\n\nLetter headings \n[…]\nied end-to-end against prodockit-userguide's real 18-term index: the\nbuilt PDF's Index page renders exactly as intended, letter groups and all.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Lay out the back-of-book index in two columns with letter headings",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T16:34:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0c35615b5b9390e89033921d77a8712915fb8925",
"body": "New capability, off by default (pdf_include_index = true under\n[project.extra] to turn it on): a traditional back-of-book index - an\nalphabetised list of terms with the page number(s) they appear on -\nappended at the very end of the PDF.\n\nMarker syntax needed real thought (per the issue's own reques\n[…]\nntent,\nconfirmed the generated index page correctly showed the right terms,\ncorrectly merged case-insensitive duplicates, and correctly resolved to\nthe right (and correctly deduplicated) page numbers.",
"is_bot": false,
"headline": "Add a back-of-book style Index, PDF-only (#55)",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-20T11:10:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a1c1c11d2ed1d802357a2e25bc9e573bd377af6c",
"body": "New prodockit.pdf.source_bundle feature (#50), plus the PDF-icon action\nbutton (#49).",
"is_bot": false,
"headline": "Bump to 0.5.0 (#53)",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-19T10:32:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a8b2d9aba244cdb6d513278c83721ae228c36639",
"body": "…(#52)\n\nNew optional capability, off by default (pdf_source_bundle = true under\n[project.extra] to turn it on): bundles every text/source file\n.gitignore doesn't exclude into a single source_bundle.pdf at the\nproject's own top-level directory (not docs_dir) - 8pt Courier, wrapped\nlines, each file st\n[…]\nges) and checked the rendered output: correct per-file page\nbreaks, correct header/footer on the first and last page, and confirmed\nno .venv/site/.git content or the PDF itself leaked into the bundle.",
"is_bot": false,
"headline": "Add prodockit.pdf.source_bundle: bundle repo source into a PDF (#50) …",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-19T10:26:35Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b4daf176de498afe3d2005510e170e06fbf198d1",
"body": "…#51)\n\nAdds overrides/partials/actions.html - a customised copy of Zensical's\nown bundled partials/actions.html (requires custom_dir = \"overrides\",\nnewly added to zensical.toml) - with a fourth action icon next to\nedit/view: a direct link to this page's own per-page PDF (see\n.github/workflows/docs.y\n[…]\n(showing prodockit\nusers the generic convention, not this site's own specific\nimplementation) is left as-is - still accurate on its own terms,\nunrelated to this project's own template-override choice.",
"is_bot": false,
"headline": "Show a PDF download icon next to \"view\", not a page-body link (#49) (…",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-19T09:53:40Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ce0a4ebb92a5696eadc693185f90b52b553743ae",
"body": "Theme config parity fixes with prodockit-userguide (#47).",
"is_bot": false,
"headline": "Bump to 0.4.2 (#48)",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-18T23:28:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6c3d8159ba7ed4d1d13498d78504946ea919a057",
"body": "* Show the actual GitHub logo in the header, not the generic Git icon\n\nMissing theme.icon.repo left Zensical's default in place (FontAwesome's\n\"git\" icon - confirmed directly by decoding the rendered header's own\nSVG path, matching git.svg's path exactly, not github.svg's) - matches\nprodockit-usergu\n[…]\ns through\nthere too.\n\nLeft theme.custom_dir (\"overrides\") out - userguide's only use for it\nis a custom GitLab icon this project's own docs never reference, so\nthere's nothing for it to point at here.",
"is_bot": false,
"headline": "Show the actual GitHub logo in the header (#47)",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-18T23:23:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5489c2c19ea4b42daba5f220709192b15096e1e0",
"body": "Docs/site chrome rework and PDF footer copyright fix (#42/#45).",
"is_bot": false,
"headline": "Bump to 0.4.1 (#46)",
"author_name": "Mark Buckwell",
"author_login": "buckwem",
"committed_at": "2026-07-18T23:00:22Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 36,
"commits_last_year": 154,
"latest_release_at": "2026-07-25T07:53:50Z",
"latest_release_tag": "prodockit-v0.10.2",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 2,
"days_since_latest_release": 0,
"mean_days_between_releases": 0.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": "prodockit",
"exists": true,
"license": "MIT",
"keywords": [
"extension",
"markdown",
"pandoc",
"pdf",
"python-markdown",
"zensical",
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Topic :: Text Processing :: Markup :: Markdown"
],
"ecosystem": "pypi",
"matches_repo": true,
"registry_url": "https://pypi.org/project/prodockit/",
"is_deprecated": false,
"latest_version": "0.10.2",
"repository_url": "https://github.com/buckwem/prodockit-extensions",
"versions_count": 25,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": "2026-07-17T09:39:06.154273Z",
"latest_published_at": "2026-07-25T07:54:31.917207Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
}
]
},
"popularity": {
"forks": 0,
"stars": 0,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": {
"days": [],
"complete": true,
"collected": 0,
"total_stars": 0,
"collected_at": null
},
"open_issues_and_prs": 8
},
"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": [
"src/prodockit/py.typed"
],
"toolchain_manifests": [],
"largest_source_bytes": 44300,
"source_files_sampled": 51,
"oversized_source_files": 0,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"pyproject.toml"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"pypi"
],
"dependencies": [
{
"name": "Markdown",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=3.4"
},
{
"name": "zensical",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": null
},
{
"name": "beautifulsoup4",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=4.12"
},
{
"name": "click",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=8.0"
},
{
"name": "pypdf",
"manifest": "pyproject.toml",
"ecosystem": "pypi",
"version_constraint": ">=4.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": 0,
"merged_prs": 65,
"open_issues": 8,
"closed_ratio": 0.724,
"closed_issues": 21,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "buckwem",
"commits": 157,
"avatar_url": "https://avatars.githubusercontent.com/u/53193258?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yml",
"docs.yml",
"publish.yml"
],
"has_docs_dir": true,
"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": 5,
"reason": "branch protection is not maximal on development and all release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 10,
"reason": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/20 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 0,
"reason": "project has 0 contributing companies or organizations -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "project was created within the last 90 days. Please review its contents carefully",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "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": "01704d39b624eb13575933cabd2416307555476d",
"ran_at": "2026-07-25T07:56:09Z",
"aggregate_score": 4,
"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-25T07:54:36Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-07-25T07:49:05Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 55,
"created_at": "2026-07-11T18:42:31Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 7,
"created_at": "2026-07-15T17:50:30Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 9,
"created_at": "2026-07-15T18:21:41Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 49,
"created_at": "2026-07-19T09:35:39Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 50,
"created_at": "2026-07-19T09:40:01Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 54,
"created_at": "2026-07-19T22:41:40Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 56,
"created_at": "2026-07-20T10:03:27Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 91,
"created_at": "2026-07-24T20:43:10Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/buckwem/prodockit-extensions",
"host": "github.com",
"name": "prodockit-extensions",
"owner": "buckwem"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"security": 40,
"vitality": 73,
"community": 24,
"governance": 50,
"engineering": 67
},
"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": 154,
"human_commit_share": 1,
"days_since_last_push": 0,
"active_weeks_last_year": 2
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "2/52 weeks with commits",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 2
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "154 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 154
}
}
],
"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": 36,
"latest_release_tag": "prodockit-v0.10.2",
"releases_from_tags": false,
"days_since_latest_release": 0,
"mean_days_between_releases": 0.4
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "36 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 36
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~0.4 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 0.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": 0,
"stars": 0,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "0 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 0
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (MIT)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "MIT"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 50,
"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": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 72,
"inputs": {
"merged_prs": 65,
"open_issues": 8,
"closed_issues": 21,
"issue_closed_ratio": 0.724,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "72% of issues closed",
"points": 33.8,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 72
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "65/65 decided PRs merged",
"points": 38.2,
"status": "met",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 65,
"decided": 65
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/20 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "at_risk",
"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": 36,
"inputs": {
"followers": 1,
"owner_type": "User",
"is_verified": null,
"owner_login": "buckwem",
"public_repos": 3,
"account_age_days": 2559
},
"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": "1 followers of buckwem",
"points": 2.2,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 1,
"login": "buckwem"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "3 public repos, account ~7 yr old",
"points": 16.4,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 3
}
},
{
"code": "account_age_years",
"params": {
"years": 7
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"prodockit"
],
"ecosystems": "pypi",
"any_deprecated": false,
"min_days_since_publish": 0
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on pypi",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "pypi"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 0 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 0
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "25 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 25
}
}
],
"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": 67,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 68,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "3 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 3
}
}
],
"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": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"topics": [],
"has_wiki": false,
"homepage": null,
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 40,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 40,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 17,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 1,
"scorecard_aggregate": 4
},
"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": 3.8,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/20 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 2
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "at_risk",
"name": "AI Readiness",
"value": 49,
"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.98,
"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": "98 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 98,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "at_risk",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 43,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": false,
"typed_language": false,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [
"src/prodockit/py.typed"
],
"agent_commit_share": 0.57,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "src/prodockit/py.typed",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "src/prodockit/py.typed"
}
}
],
"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": "57 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 57,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "good",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 82,
"inputs": {
"primary_language": "Python",
"largest_source_bytes": 44300,
"source_files_sampled": 51,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Python with type-check config (src/prodockit/py.typed)",
"points": 27,
"status": "partial",
"details": [
{
"code": "typecheck_config_language",
"params": {
"files": "src/prodockit/py.typed",
"language": "Python"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/51 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 51,
"oversized": 0
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"deps.dev does not index pypi:prodockit@0.10.2; advisories assessed against the repository dependency graph instead"
],
"report_type": "repository",
"generated_at": "2026-07-25T07:56:21.564621Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/b/buckwem/prodockit-extensions.svg",
"full_name": "buckwem/prodockit-extensions",
"license_state": "standard",
"license_spdx": "MIT"
}