Informe JSON sin procesar legible por máquina
{
"data": {
"repo": {
"topics": [
"lint",
"linter",
"markdown",
"mdbook",
"mdbook-plugins",
"mdbook-preprocessor"
],
"is_fork": false,
"size_kb": 5518,
"has_wiki": false,
"homepage": "https://joshrotenberg.com/mdbook-lint/",
"languages": {
"Rust": 2219190,
"Shell": 19145,
"Dockerfile": 830
},
"pushed_at": "2026-07-27T23:42:46Z",
"created_at": "2025-08-04T01:27:18Z",
"owner_type": "User",
"updated_at": "2026-07-27T23:42:48Z",
"description": "An mdbook linting tool",
"is_archived": false,
"is_disabled": false,
"license_spdx": null,
"default_branch": "main",
"license_spdx_raw": "NOASSERTION",
"primary_language": "Rust",
"significant_languages": [
"Rust"
]
},
"owner": {
"blog": "http://www.joshrotenberg.com",
"name": "Josh Rotenberg",
"type": "User",
"login": "joshrotenberg",
"company": "Redis",
"location": "Albany, CA",
"followers": 92,
"avatar_url": "https://avatars.githubusercontent.com/u/3231?v=4",
"created_at": "2008-03-17T16:01:18Z",
"is_verified": null,
"public_repos": 225,
"account_age_days": 6707
},
"license": {
"state": "custom",
"spdx_id": null,
"raw_spdx": "NOASSERTION",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v0.15.0",
"kind": "minor",
"published_at": "2026-07-27T23:10:23Z"
},
{
"tag": "v0.14.4",
"kind": "patch",
"published_at": "2026-06-03T04:54:33Z"
},
{
"tag": "v0.14.3",
"kind": "patch",
"published_at": "2026-03-04T01:29:55Z"
},
{
"tag": "v0.14.2",
"kind": "patch",
"published_at": "2026-02-02T16:57:44Z"
},
{
"tag": "v0.14.1",
"kind": "patch",
"published_at": "2026-02-01T22:16:24Z"
},
{
"tag": "v0.14.0",
"kind": "minor",
"published_at": "2026-02-01T20:47:52Z"
},
{
"tag": "v0.13.7",
"kind": "patch",
"published_at": "2026-01-25T06:00:01Z"
},
{
"tag": "v0.13.6",
"kind": "patch",
"published_at": "2025-12-23T22:03:30Z"
},
{
"tag": "v0.13.5",
"kind": "patch",
"published_at": "2025-12-13T04:31:41Z"
},
{
"tag": "v0.13.4",
"kind": "patch",
"published_at": "2025-12-12T16:58:10Z"
},
{
"tag": "v0.13.3",
"kind": "patch",
"published_at": "2025-12-11T21:22:24Z"
},
{
"tag": "v0.13.2",
"kind": "patch",
"published_at": "2025-12-11T17:17:36Z"
},
{
"tag": "v0.13.1",
"kind": "patch",
"published_at": "2025-12-07T15:34:43Z"
},
{
"tag": "v0.13.0",
"kind": "minor",
"published_at": "2025-12-05T06:39:29Z"
},
{
"tag": "v0.12.0",
"kind": "minor",
"published_at": "2025-12-05T04:33:09Z"
},
{
"tag": "v0.11.7",
"kind": "patch",
"published_at": "2025-12-04T16:20:59Z"
},
{
"tag": "v0.11.6",
"kind": "patch",
"published_at": "2025-09-02T14:16:07Z"
},
{
"tag": "v0.11.5",
"kind": "patch",
"published_at": "2025-08-29T15:46:23Z"
},
{
"tag": "v0.11.4",
"kind": "patch",
"published_at": "2025-08-29T04:13:35Z"
},
{
"tag": "v0.11.2",
"kind": "patch",
"published_at": "2025-08-28T20:15:50Z"
},
{
"tag": "v0.11.1",
"kind": "patch",
"published_at": "2025-08-25T21:38:41Z"
},
{
"tag": "v0.11.0",
"kind": "minor",
"published_at": "2025-08-25T17:52:12Z"
},
{
"tag": "v0.10.0",
"kind": "minor",
"published_at": "2025-08-15T21:26:36Z"
},
{
"tag": "v0.9.0",
"kind": "minor",
"published_at": "2025-08-15T20:40:59Z"
},
{
"tag": "v0.6.0",
"kind": "minor",
"published_at": "2025-08-08T15:23:23Z"
},
{
"tag": "v0.5.0",
"kind": "minor",
"published_at": "2025-08-08T05:17:13Z"
},
{
"tag": "v0.4.1",
"kind": "patch",
"published_at": "2025-08-08T00:09:36Z"
},
{
"tag": "v0.4.0",
"kind": "minor",
"published_at": "2025-08-07T20:33:07Z"
},
{
"tag": "v0.3.0",
"kind": "minor",
"published_at": "2025-08-05T17:05:26Z"
},
{
"tag": "v0.2.0",
"kind": "minor",
"published_at": "2025-08-05T02:38:25Z"
},
{
"tag": "v0.1.0",
"kind": "minor",
"published_at": "2025-08-04T18:52:48Z"
}
],
"recent_commits": [
{
"oid": "e67ca47a9cf54e1d1fd88e3e84ab898a771df3e5",
"body": "…a bump (#450)\n\nThe update-homebrew job pinned mislav/bump-homebrew-formula-action@v3.1, which\ndownloads the source tarball with the COMMITTER_TOKEN attached to compute its\nSHA256. For authenticated archive requests GitHub responds with 303 See Other\n(to drop the Authorization header on the cross-ho\n[…]\ny on the last two releases (v0.14.4, v0.15.0),\nleaving the tap behind.\n\nv4 follows the redirect. Uses a major-version tag to match the pinning style of\nthe other actions in this workflow.\n\nCloses #449",
"is_bot": false,
"headline": "ci: bump bump-homebrew-formula-action to v4 to fix HTTP 303 on formul…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T23:42:44Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "150ad22698466ff0e2e6382a550b833e64b857cb",
"body": null,
"is_bot": false,
"headline": "chore: release v0.15.0 (#429)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T23:04:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "440b9dcfdfade3258c4b96870591411e5f0de1ef",
"body": "…config (#448)\n\nexample-mdbook-lint.toml is embedded in the binary via include_str! and\nwritten verbatim by `mdbook-lint init`, so every generated config carried\ncommented per-rule options for MDBOOK002/003/004/006/007/008/009/010/011/012\nthat no rule reads. Uncommenting any of them is a silent no-o\n[…]\nion\" header is retained, so the documented-rule count\nis unchanged.\n\nAddresses the shipped-in-binary portion of #416, #417, and #418; those issues\nstay open to track implementing the options for real.",
"is_bot": false,
"headline": "docs(config): stop shipping fictional MDBOOK rule options in example …",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T22:57:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "85ce3fefd14803bbe311a3846560a7bdc0887b23",
"body": "…se-positive (#447)\n\nMD032 computed a list's end line by taking the maximum start line across the\nlist's descendants. A multi-line block inside a list item, such as a fenced\ncode block, starts on one line but ends several lines later, so the computed\nend landed on the block's opening line and the bl\n[…]\n on the real last line of\ncontent. Genuine cases (a separate block placed immediately after a list with\nno blank line) still flag.\n\nAddresses the MD032 half of #438; the MD030 half is handled in #446.",
"is_bot": false,
"headline": "fix(md032): use node end lines so code fences in list items don't fal…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T22:42:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "515d56f8deb2bbb4b785ef2866aa70e928bdde34",
"body": "MD030 classified a line starting with `*` as emphasis only when the closing\n`*` fell within the first 50 characters. An emphasized sentence longer than\nthat was read as an unordered list marker followed by zero spaces, and\nflagged.\n\nReported in #438: three consecutive `*Rejected - ...*` paragraphs, \n[…]\nine with no closing `*`, such as `*No space after marker`, is still\nreported as a missing space after a list marker.\n\nCovers only the MD030 half of #438; the MD032 fence-in-list-item case is\nseparate.",
"is_bot": false,
"headline": "fix(md030): do not treat a long emphasis span as a list marker (#446)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T22:42:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a39a043fdf3c93f0e2ea01ae7bdd43e194d14867",
"body": "…kers (#445)\n\ncomrak folds leading YAML frontmatter into a FrontMatter node and\nrenumbers every following node as if the document began at line 1. #430\nadded Document::frontmatter_ast_offset for this and applied it to MD041,\nMD022 and MD007, but MD004 was not updated.\n\nMD004 takes a list item's line\n[…]\n `---` delimiter to `***`.\n\nAdd the frontmatter offset to the AST line before the marker is read, as\nMD022 already does. Violation positions and fixes then refer to the real\nsource lines.\n\nCloses #441",
"is_bot": false,
"headline": "fix(md004): account for frontmatter line offset when reading list mar…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T16:55:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "20b76f32f7059bb39c49704a4bc5535298dec788",
"body": "Adr007::from_config only read the `format` key, so a `[ADR007]\nvalid-statuses = [...]` table parsed into rule_configs but never reached\nthe rule. The rule always ran with the built-in status list, and the\n\"Valid values\" line in its warning always listed the built-in statuses\nrather than the configur\n[…]\nes` (and the `valid_statuses` spelling) in from_config\nand replace the default list when the value is a non-empty array. A\nmissing, non-array, or empty value leaves the defaults in place.\n\nCloses #437",
"is_bot": false,
"headline": "fix(adr): honor ADR007 valid-statuses configuration (#444)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T14:22:02Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "87d08db53eb43704ea940fe3b7f68ce536299d0d",
"body": "…g them (#442)\n\nGlobal config fields were deserialized with an explicit kebab-case\n`rename` and no `alias`. Because `rule_configs` is `#[serde(flatten)]`\ninto a map, a snake_case key such as `disabled_rules` did not error: it\nlanded in `rule_configs` under that name and had no effect, with no\nwarnin\n[…]\nrialization.\n\nNormalize the example files to kebab-case and drop `default_severity`,\nwhich is documented in two example files but does not exist as a field\nin `Config` under any spelling.\n\nCloses #419",
"is_bot": false,
"headline": "fix: accept snake_case global config keys instead of silently ignorin…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T13:50:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5dcf592ccf76dc4e82ab7b11abf2604bd65c24b4",
"body": "…440)\n\n* fix: derive init --include-all rule count instead of hardcoding it\n\n`mdbook-lint init --include-all` printed \"all 78 available rules\", a\nhardcoded literal that drifted from the embedded example config it\ndescribes. README and docs/src/configuration.md separately claimed 83.\nThe example conf\n[…]\nREADME.md\", so cargo\nrelocates README.md to the package root when packaging, and the\ncompile-time path would not resolve there. Read it at runtime from\nCARGO_MANIFEST_DIR instead and skip when absent.",
"is_bot": false,
"headline": "fix: derive init --include-all rule count instead of hardcoding it (#…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-27T00:24:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "475c6e41e4f0625897edcff94b4228c85d9cee0f",
"body": "…439)\n\nThe repository root is a virtual workspace manifest, so `cargo install\n--path .` fails with \"found a virtual manifest ... instead of a package\nmanifest\". Point the path at `crates/mdbook-lint-cli`, which holds the\ninstallable binary crate.\n\nAlso replace the hardcoded `mdbook-lint 0.1.0` verification sample with a\ngeneric `x.y.z` placeholder so it does not go stale on each release.",
"is_bot": false,
"headline": "docs: fix From Source install path and stale version sample (#424) (#…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-23T04:42:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c978da303c9f4cae8dc6b652c9c092aad8050ed3",
"body": "Reference link/image definitions put an unwrappable destination on their\nown line (`[label]: https://long-url`). A long one triggered MD013 with\nno way to fix it. The new ignore_reference_definitions option (default\nfalse, so behavior is unchanged) skips these lines.\n\n- Add the field + config parsing (snake_case and kebab-case).\n- Skip reference-definition lines in should_ignore_line when enabled.\n- Document the option in the example config and the MD013 rule page.\n\nCloses #407",
"is_bot": false,
"headline": "feat: add MD013 ignore_reference_definitions option (#436)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-23T04:41:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b3d4d8e1bb2ac9c370d7172dffdf5392a25d7c19",
"body": "* fix: resolve ADR format detection false positives (#408, #409)\n\ndetect_format previously classified any file with YAML frontmatter as\nMADR4, misclassifying the adrs tool's 'ng' mode output (frontmatter +\nNygard sections) and firing false ADR004/ADR005 errors. is_adr_document\nonly recognized adr/ad\n[…]\nard title after an SPDX/REUSE comment header; plain non-ADR doc.\n- ADR004 regression: a ng+Nygard document is not flagged for a missing\n MADR 'Context and Problem Statement' section.\n\nRefs #408, #409",
"is_bot": false,
"headline": "fix: resolve ADR format detection false positives (#408, #409) (#435)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-23T04:41:48Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ed69dfd06310eb671b5b80e216280c7092afa135",
"body": "* fix: wire ADR provider rule configuration (format override)\n\nAdrRuleProvider never implemented register_rules_with_config, so the\ndocumented provider-level [ADR] format = auto|nygard|madr override was a\nsilent no-op: every ADR rule always auto-detected the format per document.\n\n- Add from_config t\n[…]\ntest on ADR001 (format parsing + unknown-value fallback)\n- provider-level threading test: [ADR] format = madr overrides Nygard\n auto-detection end-to-end, making the MADR-only ADR004 apply\n\nRefs #414",
"is_bot": false,
"headline": "fix: wire ADR provider rule configuration (format override) (#434)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-23T04:41:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1fc838c4d50dc22f63819b9dcdad2432fe585704",
"body": "* fix: wire CONTENT provider rule configuration\n\nContentRuleProvider never implemented register_rules_with_config, so it\nfell through to the trait default and ignored all configuration. None of\nthe CONTENT rules had from_config, so every documented per-rule option\nwas a silent no-op.\n\n- Implement re\n[…]\npose and real config keys.\n- Add from_config unit tests (CONTENT001/004/007/009) and a provider-level\n regression test asserting CONTENT009 max_depth threads through\n ContentRuleProvider.\n\nRefs #415",
"is_bot": false,
"headline": "fix: wire CONTENT provider rule configuration (#432)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-23T04:41:23Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f6db2ed3e59ac2408b74fabf7f5086b097c2f0a8",
"body": "* feat: add ignore-paths field to core Config\n\nBacking field for the documented global ignore-paths option. Accepts\nboth ignore-paths and ignore_paths spellings. Filtering is wired up in\nthe CLI in a follow-up commit.\n\nRefs #411\n\n* fix: thread rule config to mdbook rules and honor MDBOOK005 ignore_p\n[…]\ne semantics: trailing slash is a directory\n prefix, slash-less patterns match at any depth, * does not cross\n separators while ** does.\n- Document the option in the configuration guide.\n\nCloses #411",
"is_bot": false,
"headline": "fix: honor ignore-paths and MDBOOK005 ignore_patterns config (#413)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-23T04:41:13Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5810af1f1da6ed2968985f4a5b690a96f052cc64",
"body": "RUSTSEC-2026-0204 (published 2026-07-07) flags crossbeam-epoch < 0.9.20\nfor an invalid pointer dereference in the fmt::Pointer impl for Atomic\nand Shared. It reaches the tree via rayon -> crossbeam-deque. The fix is\na lockfile-only bump to the patched 0.9.20; cargo audit exits 0 again.\n\nRefs #425",
"is_bot": false,
"headline": "chore(deps): bump crossbeam-epoch to 0.9.20 (#433)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-07T14:44:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "037c4203346e9e74667aa89b76a0889ef77bb73c",
"body": "The Security Audit CI job failed on two quick-xml advisories\n(RUSTSEC-2026-0194/0195), pulled in transitively via comrak's default\nsyntect feature (comrak -> syntect -> plist -> quick-xml). The codebase\nonly uses comrak's parser/AST, never its syntect HTML highlighting or\nits cli binary.\n\n- Set comr\n[…]\nhe only\nremaining advisory is proc-macro-error2 (unmaintained) via tabled, which\nis an informational warning that does not fail the audit; tabled 0.21\nstill pulls it, so no bump was made.\n\nCloses #425",
"is_bot": false,
"headline": "chore(deps): drop comrak syntect/cli defaults and update anyhow (#426)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-07T14:09:14Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a00c10728aecbcb78c9d42a2d1c54e5ce695150c",
"body": "…(#431)\n\nMD051, CONTENT006, and MDBOOK006 flagged valid link fragments for\nduplicate headings (e.g. a second \"Details\" heading resolves to\n`details-1` in mdBook, but the rules did not accept it).\n\nmdBook assigns unique heading ids with a zero-based counter: the first\noccurrence of a normalized id is\n[…]\nte-heading case is\nvalid, and a genuinely broken fragment still errors. MD051's tests use\nthe AST path, since the default check routes through a fallback that\ndoes not validate fragments.\n\nCloses #410",
"is_bot": false,
"headline": "fix: duplicate-heading link fragments match mdBook unique ids (#410) …",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-07T01:14:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6e282729195f5bc0d5a0a575eb527af627c6b44e",
"body": "comrak recognizes leading YAML frontmatter and folds it into a\nFrontMatter node, but it renumbers every following node as if the\ndocument began at line 1. The standard rules did not account for this,\nso on any document with frontmatter the `---` delimiters and YAML keys\nwere linted as Markdown:\n\n- M\n[…]\nes use\nthe real source lines. MD007 skips frontmatter lines and shifts its\ncode-block ranges by the offset. Genuine violations in the body are still\nreported, at the correct source lines.\n\ncloses #406",
"is_bot": false,
"headline": "fix: standard rules ignore YAML frontmatter (MD041, MD022, MD007) (#430)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-07T00:41:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "014fbbd9280f3da8ee52df0e04e9134a2f5a5e82",
"body": "Config supports neither a per-path [[overrides]] array-of-tables nor an\n[output] table. Both were documented as working across first-party docs;\ncopying them into a config yields no error and no effect because unknown\ntop-level keys fall into the flattened rule_configs map and are ignored.\n\nRemove t\n[…]\nfile example with the real\n inline <!-- mdbook-lint-disable --> directive.\n- mdbook005.md: drop the fictional per-directory [[overrides]] example;\n global disable is already documented.\n\ncloses #421",
"is_bot": false,
"headline": "docs: remove fictional [[overrides]] and [output] config sections (#428)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-06T23:46:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ae77b035123df3d3c29ca5cf0893da1c63fe39af",
"body": "…/env vars (#427)\n\n* docs: correct rules subcommand options in cli-usage (#422)\n\nThe --enabled flag does not exist on the rules subcommand, and\n--format accepts default/json (not text/JSON). Document the real\nflags from main.rs Commands::Rules.\n\n* docs: remove nonexistent env vars and add missing su\n[…]\ne, and env-var docs;\n neither is read anywhere in the code. Point to --config instead.\n- getting-started.md, configuration.md: replace the nonexistent\n 'rules --enabled' examples with real commands.",
"is_bot": false,
"headline": "docs: fix cli-usage and configuration references to nonexistent flags…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-07-06T23:37:48Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3ee3dd0dc815dcfe8b4d11cfef2a411348448bc0",
"body": null,
"is_bot": false,
"headline": "chore: release v0.14.4 (#396)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-06-03T04:46:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b70c7b6185af33e7059487f5c677bb0d076356fd",
"body": "* feat: validate number field in MADR frontmatter in ADR009\n\n* chore: apply cargo fmt",
"is_bot": false,
"headline": "feat: ADR009 validates number field in MADR frontmatter (#405)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-06-03T04:40:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "251e2b3ce0a7e488c0aea4a53794079e255732ea",
"body": "Bumps [rand](https://github.com/rust-random/rand) from 0.9.2 to 0.9.4.\n- [Release notes](https://github.com/rust-random/rand/releases)\n- [Changelog](https://github.com/rust-random/rand/blob/0.9.4/CHANGELOG.md)\n- [Commits](https://github.com/rust-random/rand/compare/rand_core-0.9.2...0.9.4)\n\n---\nupda\n[…]\nand\n dependency-version: 0.9.4\n dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump rand from 0.9.2 to 0.9.4 (#398)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-03T04:37:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c94b9daec408c88f14cf5044fb2b716c5b1c0165",
"body": "ADR014: Replace substring matching with word-boundary regex for\nplaceholder detection. \"described\" in legitimate text no longer matches\nthe \"describe\" placeholder pattern.\n\nADR010: Add regex for bare ADR filename links (NNNN-slug.md) without\ndirectory prefix. The adrs CLI and adr-tools generate this format.\n\nCloses joshrotenberg/adrs#197\nCloses joshrotenberg/adrs#198",
"is_bot": false,
"headline": "fix: resolve ADR010 and ADR014 false positives (#404)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-06-03T04:18:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4c73b32f9f21e92c8efa71148939535132dfbf41",
"body": "* chore: start work on #401\n\n* feat: wire ADR rule provider into CLI and preprocessor\n\n* fix: resolve CI failures -- fmt in mdbook004 and disable ADR rules in rustdoc step",
"is_bot": false,
"headline": "feat: expose ADR ruleset (ADR001-ADR017) in CLI (#402)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-06-03T00:11:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "828fa4fea0ff198fe331ec8e741c19e21c41b543",
"body": "…6, MDBOOK006 (#403)\n\n* chore: start work on #399\n\n* fix: use Unicode-aware lowercasing in anchor generation",
"is_bot": false,
"headline": "fix: resolve false positives for Unicode headings in MD051, CONTENT00…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-06-03T00:05:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bde598e74e69693e10204c5b99086ede53bf353f",
"body": null,
"is_bot": false,
"headline": "Add edge cases for MDBOOK04 (#355)",
"author_name": "Evers",
"author_login": "Evers-Perez",
"committed_at": "2026-03-08T07:34:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "55084229e962ff39a0f0c436d70e46f1e2392c20",
"body": null,
"is_bot": false,
"headline": "chore: release v0.14.3 (#389)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-03-04T01:23:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1463c786cb0ee7e2816df5c16e51b08e7e1b21a1",
"body": "ADR014: Replace substring matching with word-boundary regex for\nplaceholder detection. \"described\" in legitimate text no longer matches\nthe \"describe\" placeholder pattern.\n\nADR010: Add regex for bare ADR filename links (NNNN-slug.md) without\ndirectory prefix. The adrs CLI and adr-tools generate this format.\n\nCloses joshrotenberg/adrs#197\nCloses joshrotenberg/adrs#198",
"is_bot": false,
"headline": "fix: resolve ADR010 and ADR014 false positives (#394)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-03-04T01:17:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "36b05578aeb07de701398ca1b8b34344d970adad",
"body": "MD058: Replace raw text scanning (find_table_segments) with AST-based\ntable boundary detection. The old approach scanned beyond table AST\nnodes and flagged pipe characters in code blocks and list items as\ntable formatting violations.\n\nMD041: Skip HTML comments when finding the first content line. Files\nstarting with <!-- mdbook-lint-disable --> comments followed by an H1\nheading are now correctly recognized.\n\nCloses #393\nCloses #392",
"is_bot": false,
"headline": "fix: resolve MD058 and MD041 false positives (#395)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-03-04T01:17:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5c4ca12b3a06e12241cbefa2d554e48b526926f5",
"body": "Bumps [time](https://github.com/time-rs/time) from 0.3.41 to 0.3.47.\n- [Release notes](https://github.com/time-rs/time/releases)\n- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/time-rs/time/compare/v0.3.41...v0.3.47)\n\n---\nupdated-dependencies:\n- d\n[…]\nme\n dependency-version: 0.3.47\n dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump time from 0.3.41 to 0.3.47 (#390)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-03-04T01:10:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "920a9c9cb2daf23ae04dbe15ece939c61f39c362",
"body": "Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.10.1 to 1.11.1.\n- [Release notes](https://github.com/tokio-rs/bytes/releases)\n- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/tokio-rs/bytes/compare/v1.10.1...v1.11.1)\n\n---\nupdated-depend\n[…]\nes\n dependency-version: 1.11.1\n dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump bytes from 1.10.1 to 1.11.1 (#391)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-03-04T01:10:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "479d5452d475b69b0b6f5f5038dbdf30addf401b",
"body": null,
"is_bot": false,
"headline": "docs: update Docker version examples to 0.14.2 (#388)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-02T23:07:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9dc39d6f5bf6f93f942b8f6d985e3d3d5bbb85ce",
"body": null,
"is_bot": false,
"headline": "chore: release v0.14.2 (#385)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-02T16:48:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b6aa86b45261c2cbf89ec8c313cf0bdda4502f16",
"body": "- Change base image to rust:slim-bookworm (latest stable)\n- Rust 1.85+ required for edition 2024 support\n- Add Docker installation section to README with usage examples",
"is_bot": false,
"headline": "fix: update Dockerfile for Rust edition 2024 and add Docker docs (#387)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-02T15:58:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b23de986ae63292e3b7f9eb11faf3415a5339882",
"body": "* docs: add RELEASE.md documenting the release process\n\nExplains the automated release flow using release-plz, cargo-dist, and\ngit-cliff, including configuration files, secrets, troubleshooting, and\nexpected artifacts.\n\n* feat: add Docker image build and push workflow\n\n- Add Dockerfile with multi-st\n[…]\nild and push to ghcr.io on releases\n- Update RELEASE.md with Docker documentation\n\nDocker images will be available at ghcr.io/joshrotenberg/mdbook-lint\nwith tags for version, minor, major, and latest.",
"is_bot": false,
"headline": "docs: add RELEASE.md documenting the release process (#386)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T22:24:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "cecf084e9360daee717f9543d7fc76c4c4aff29d",
"body": null,
"is_bot": false,
"headline": "chore: release v0.14.1 (#384)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T22:06:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f13df08524599516bbc6b175ac9e066b9e089a4d",
"body": "The rulesets and cli crates depend on mdbook-lint-core with a version\nrequirement. During version bumps, cargo package fails because the new\nversion isn't published to crates.io yet. The --no-verify flag doesn't\nhelp because dependency resolution still happens during packaging.\n\nOnly check the core crate (which has no internal dependencies).\nrelease-plz handles correct publish order when actually releasing.",
"is_bot": false,
"headline": "fix: remove dry-run package checks for workspace-dependent crates (#383)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T22:01:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a60c10eccf72610f88cce37fc7ecb71ef436ae01",
"body": "When a fix replacement ends with a newline and the original content\nhas a newline at the end position, skip the original newline to avoid\ndouble newlines. This is common when rules create fixes that replace\nentire lines including their trailing newline.\n\nFixes #378",
"is_bot": false,
"headline": "fix: handle newline duplication in apply_fix methods (#381)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T21:43:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0fae4d14e8b1132474d859d7bf3f623eaa532dc9",
"body": "Using GITHUB_TOKEN prevents tag pushes from triggering other workflows\n(GitHub security feature). Switching to a PAT (RELEASE_TOKEN) allows\nthe cargo-dist release workflow to trigger automatically when release-plz\ncreates a version tag.",
"is_bot": false,
"headline": "fix: use PAT for release-plz to trigger cargo-dist workflow (#380)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T21:12:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "46bb0cd6e84716cbca4702f820ffc5a545aaedfd",
"body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore: release v0.14.0 (#373)",
"author_name": "github-actions[bot]",
"author_login": "github-actions[bot]",
"committed_at": "2026-02-01T20:36:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bf9a300dfa00edbdc4247566ab07527f56251415",
"body": "The remote.github.owner and remote.github.repo variables are not\navailable when release-plz runs git-cliff, causing changelog\ngeneration to fail.",
"is_bot": false,
"headline": "fix: use hardcoded GitHub URL in cliff.toml template (#377)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T17:01:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c959795406c6107b7351d40fac68315fbf71d388",
"body": "* feat: improve library ergonomics for external consumers\n\nAdd convenience methods to LintEngine:\n- apply_fix(content, violation) - apply a single fix\n- apply_fixes(content, violations) - apply all available fixes\n- Rename path parameter to source_label in lint_content for clarity\n\nAdd re-exports an\n[…]\n (now: create_default_engine())\n- Applying fixes awkward (now: engine.apply_fixes())\n- Two crates always needed (now: rulesets re-exports core types)\n\n* fix: remove undefined reference link in rustdoc",
"is_bot": false,
"headline": "feat: improve library ergonomics for external consumers (#372)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T16:02:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3544addcbefb8ce7b1ead7224996c19825655d69",
"body": "* docs: add comprehensive ADR ruleset documentation\n\nAdd documentation for all 17 ADR rules (ADR001-ADR017):\n- Create docs/src/rules/adr/index.md with overview, format examples,\n configuration, and CI integration guidance\n- Add individual documentation pages for each rule\n- Update SUMMARY.md with A\n[…]\nx MD032 warnings\n- Add blank lines before fenced code blocks to fix MD031 warnings\n- Add intro text after main heading to fix CONTENT005 warning\n\n* fix: add missing blank line before list in adr003.rs",
"is_bot": false,
"headline": "fix: add missing blank line in adr003.rs rustdoc (#376)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T16:02:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "35bf1d14d5888e5e7c5008c8aa683b4f47315e83",
"body": "* fix: output correct JSON format for mdbook 0.5.x\n\nWhen receiving mdbook 0.5.x input (which uses \"items\" instead of \"sections\"),\nthe preprocessor now correctly outputs JSON in 0.5.x format.\n\nPreviously, the preprocessor would:\n1. Normalize input: items -> sections (for deserialization)\n2. Process t\n[…]\nes:\n- nested_chapters_v04.json (mdbook 0.4.x format with sections)\n- nested_chapters_v05.json (mdbook 0.5.x format with items)\n- violations_input_v05.json (mdbook 0.5.x format with linting violations)",
"is_bot": false,
"headline": "test: add comprehensive mdbook 0.4/0.5 compatibility tests (#374)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T15:29:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "153f675066eeccb0ac060f57add0d243362be0c4",
"body": "* docs: add comprehensive ADR ruleset documentation\n\nAdd documentation for all 17 ADR rules (ADR001-ADR017):\n- Create docs/src/rules/adr/index.md with overview, format examples,\n configuration, and CI integration guidance\n- Add individual documentation pages for each rule\n- Update SUMMARY.md with A\n[…]\nR rustdoc comments\n\n- Add blank lines before lists to fix MD032 warnings\n- Add blank lines before fenced code blocks to fix MD031 warnings\n- Add intro text after main heading to fix CONTENT005 warning",
"is_bot": false,
"headline": "fix: correct markdown formatting in ADR rustdoc comments (#375)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T15:29:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "09e87353885af58b7ebf5abe1bed0ca9ab95b454",
"body": "* feat: replace release-binaries workflow with cargo-dist\n\n- Add cargo-dist for building and distributing release binaries\n- Configure release-plz to create tags but not GitHub releases\n- cargo-dist now handles GitHub release creation with binaries\n- Build targets: macOS (ARM/Intel), Linux (ARM/Inte\n[…]\n#368\n\n* feat: configure release-plz to use git-cliff for changelog\n\nAdd changelog_config = \"cliff.toml\" to tell release-plz to use git-cliff\nfor changelog generation instead of its built-in generator.",
"is_bot": false,
"headline": "feat: replace release-binaries workflow with cargo-dist (#371)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T14:51:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "327751dde8522de998ab9acd854b0646c8bc39ec",
"body": "* fix: output correct JSON format for mdbook 0.5.x\n\nWhen receiving mdbook 0.5.x input (which uses \"items\" instead of \"sections\"),\nthe preprocessor now correctly outputs JSON in 0.5.x format.\n\nPreviously, the preprocessor would:\n1. Normalize input: items -> sections (for deserialization)\n2. Process t\n[…]\nrom core (book_src_dir field) that\naren't published yet. cargo package --no-verify skips build verification\nagainst crates.io dependencies. Actual publishing order is handled\ncorrectly by release-plz.",
"is_bot": false,
"headline": "fix: mdbook 0.5.x compatibility fixes (#370)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T14:50:37Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3502d272b8fe75f7b2ed32dd9ab1c15a1da3dcf5",
"body": "Release binaries were not being built since v0.11.7 because release-plz\ncreates releases with GITHUB_TOKEN, which doesn't trigger other workflows.\n\nChanges:\n- Add workflow_dispatch trigger with tag input to release-binaries.yml\n- Replace deprecated actions/upload-release-asset@v1 with gh release upload\n- Add build-binaries job to release-plz.yml that triggers binary builds\n- Add actions: write permission to release-plz.yml\n\nFixes #368",
"is_bot": false,
"headline": "fix: trigger release binaries from release-plz workflow (#369)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-02-01T14:26:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7769425319d831215c25cdf1551ae305c6fecb11",
"body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore: release v0.13.7 (#349)",
"author_name": "github-actions[bot]",
"author_login": "github-actions[bot]",
"committed_at": "2026-01-25T05:57:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "27f09eff0a2298b809777fe40cf2cd4c50c60335",
"body": "Add documentation for all 17 ADR rules (ADR001-ADR017):\n- Create docs/src/rules/adr/index.md with overview, format examples,\n configuration, and CI integration guidance\n- Add individual documentation pages for each rule\n- Update SUMMARY.md with ADR rules section\n- Update rules/index.md to include A\n[…]\nts (100 total)\n\nThe ADR ruleset validates Architecture Decision Records against both\nNygard and MADR 4.0 formats, including structure validation, content\nquality checks, and collection-level analysis.",
"is_bot": false,
"headline": "docs: add comprehensive ADR ruleset documentation (#364)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-01-25T05:41:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e5d7125ff10aeff44546cac018aee6c5e278e2a2",
"body": "Add content quality rules for Architecture Decision Records:\n\n- ADR014: Validates that required sections have meaningful content,\n not placeholders like TODO, TBD, or ellipsis\n- ADR015: Validates that Decision Drivers section uses bullet list\n format (MADR only)\n- ADR016: Validates that Considered Options section lists at least\n 2 options (MADR only)\n- ADR017: Validates that Consequences section distinguishes good/bad\n outcomes using structured format (MADR only)",
"is_bot": false,
"headline": "feat: add ADR content quality rules (ADR014-ADR017) (#363)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-01-25T05:23:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "48c441764c70c29a0d519c46de37950c755ab760",
"body": "Add multi-document ADR rules that analyze collections of ADR files:\n\n- ADR010: Superseded ADRs must reference their replacement\n- ADR011: ADR numbers should be sequential with no gaps\n- ADR012: Each ADR number must be unique (no duplicates)\n- ADR013: Links to other ADRs must point to existing files\n\nIntroduces CollectionRule trait in mdbook-lint-core for rules that\nneed to analyze multiple documents together, with corresponding\nregistry and engine support.",
"is_bot": false,
"headline": "feat: add ADR collection rules (ADR010-ADR013) (#362)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-01-25T05:11:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bde1100824925945b662c4a29d91f1c9d1aa782b",
"body": "Add six new ADR rules for comprehensive validation:\n\n- ADR004: Required context section (## Context or ## Context and Problem Statement)\n- ADR005: Required decision section (## Decision or ## Decision Outcome)\n- ADR006: Required consequences section (Nygard format only)\n- ADR007: Valid status values\n[…]\nrejected, draft)\n- ADR008: Date format validation (ISO 8601 YYYY-MM-DD)\n- ADR009: Filename matches ADR number (Nygard format only)\n\nAll rules support both Nygard and MADR 4.0 formats where applicable.",
"is_bot": false,
"headline": "feat: add ADR rules batch 2 (ADR004-ADR009) (#361)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-01-25T04:38:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "65a1723ddef9dc5b8292041ecc78015c02e3b6ee",
"body": "Add a new optional ruleset for linting Architecture Decision Records:\n\n- ADR001 (adr-title-format): Validates title format for ADR type\n- ADR002 (adr-required-status): Ensures status is defined\n- ADR003 (adr-required-date): Ensures date is defined\n\nSupports both Nygard format (numbered titles, Date:\n[…]\nn adr/ or adrs/ directories, or with ADR content markers).\n\nEnable with the `adr` Cargo feature flag.\n\nNote: CLI integration will be added in a follow-on PR after this crate\nis published to crates.io.",
"is_bot": false,
"headline": "feat: add ADR ruleset for Architecture Decision Records (#360)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-01-25T02:39:49Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "532f23999463a0c53313371c3acd897f14a01b0f",
"body": "Adds proptest-based property tests to verify slug generation invariants:\n\n- slug_contains_only_valid_chars: slugs only contain alphanumeric, -, _\n- slug_is_lowercase: all slugs are lowercase\n- slug_no_leading_trailing_hyphens: no leading/trailing hyphens\n- alphanumeric_preserved: pure alphanumeric t\n[…]\nere the unit tests used\nthe fallback code path (None AST) but the CLI used the real AST path.\nThe property tests explicitly test the AST path.\n\nAlso includes the fix for #356 (merged from fix branch).",
"is_bot": false,
"headline": "test: add property tests for slug generation (#359)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-01-25T00:41:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1d20a24c88b0ad3ca17264cbbd4c2a886287be5c",
"body": "The slug generation algorithm was incorrectly replacing all\nnon-alphanumeric characters (except - and _) with hyphens. However,\nmdBook only converts whitespace to hyphens and removes other\npunctuation.\n\nFor heading `## \\`a\\` + \\`title\\``:\n- Before: Generated slug `a---title` (space, plus, space -> h\n[…]\nspace\n- Fix generate_anchor() in CONTENT006 with the same algorithm\n- Add test_issue_356_backticks_with_plus_using_ast to verify AST path\n- Update related tests to match corrected behavior\n\nFixes #356",
"is_bot": false,
"headline": "fix: correct slug generation to match mdBook behavior (#358)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-01-24T20:25:48Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7729351bc2208814cd16b38a4a2d9ab606411400",
"body": "* feat: add rustdoc subcommand to lint //! module docs\n\nAdd a new 'rustdoc' subcommand that extracts module-level documentation\ncomments (//!) from Rust source files and lints them as markdown.\n\nFeatures:\n- Extracts //! comments from .rs files\n- Recursively scans directories (skips .hidden and targe\n[…]\ns in lib.rs docs and rule documentation (blank lines before lists)\n- Add rustdoc linting to CI workflow\n\n* test: add integration tests for rustdoc subcommand\n\n* docs: add rustdoc linting documentation",
"is_bot": false,
"headline": "feat: add rustdoc subcommand to lint //! module docs (#352)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2026-01-07T19:31:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9da5d8ad53e20d97ca51ca61a21f5d10d0d2688f",
"body": null,
"is_bot": false,
"headline": "test: add edge case tests for MD002 first-heading-h1 rule (#351)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-26T16:39:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c5170799da97d5377c28ca237a723ebaddee7c78",
"body": null,
"is_bot": false,
"headline": "test: add edge case tests for MD001 heading-increment rule (#350)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-26T16:31:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3a87d674e3826752d54c97c97233dc32277950aa",
"body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore: release v0.13.6 (#344)",
"author_name": "github-actions[bot]",
"author_login": "github-actions[bot]",
"committed_at": "2025-12-23T21:59:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c9946393dc3d5d5d214326950bdaf9be4ab7c8a2",
"body": "The RefDefParser was not recognizing reference link definitions that\nappear inside blockquotes because it only skipped whitespace at the\nstart of lines, not blockquote markers.\n\nExample that now works:\n> Some text with a [link][ref].\n>\n> [ref]: https://example.com\n\nChanges:\n- Added skip_blockquote_m\n[…]\n_whitespace() in next_definition()\n- Handles nested blockquotes (>>, >>>, etc.)\n- Handles various spacing patterns (>, > , > , etc.)\n- Added 6 comprehensive tests for blockquote scenarios\n\nFixes #345",
"is_bot": false,
"headline": "fix: recognize reference definitions inside blockquotes in MD052 (#348)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-23T21:43:36Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d61efa2ff020f5404bd675952c7b3c2019d2fb01",
"body": "The code_blocks option was documented but not implemented. This adds:\n\n- code_blocks field to MD010 struct (default: true)\n- Parsing of code_blocks/code-blocks in from_config()\n- Logic to skip checking inside fenced code blocks when code_blocks=false\n- Support for both backtick and tilde fenced code\n[…]\nunctionality\n\nWhen code_blocks=false, tabs inside fenced code blocks are not flagged,\nwhich is useful for documentation containing assembly code, Makefiles,\nor other tab-sensitive content.\n\nFixes #346",
"is_bot": false,
"headline": "fix: implement code_blocks config option for MD010 (#347)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-23T21:39:03Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "487420d2b5f41e71926b1442485e5fb72e5c41f1",
"body": "MD052 was incorrectly flagging IPA (International Phonetic Alphabet)\ntranscriptions in square brackets as undefined reference links.\n\nExamples that are now correctly ignored:\n- [ˈkaza] (primary stress mark)\n- [paʃ] (IPA consonant)\n- [ˈbɛːo] (stress + vowel + length mark)\n\nChanges:\n- Add contains_ipa\n[…]\nength marks)\n- U+0300-U+036F: Combining Diacritical Marks\n- U+1D00-U+1DBF: Phonetic Extensions\n- Latin Extended characters used in IPA (θ, ð, ŋ, click consonants)\n- Greek letters used in IPA (θ, β, χ)",
"is_bot": false,
"headline": "fix: skip IPA phonetic notation in MD052 reference link checks (#343)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-19T07:35:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3090d9131d0fddbc8d4e016ab7f6f28b077f5150",
"body": "Add changelog_include to mdbook-lint package config so commits that\nonly touch mdbook-lint-core or mdbook-lint-rulesets are included in\nthe main changelog.\n\nThis was the root cause of missing PRs in v0.13.5 - commits that only\nmodified rule files were attributed to mdbook-lint-rulesets, but that\npackage had changelog_update=false.",
"is_bot": false,
"headline": "fix: include dependency crate commits in changelog (#342)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T04:49:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c14141cb9d60a28effdadebd71d20658a0c2a3ed",
"body": null,
"is_bot": false,
"headline": "docs: complete v0.13.5 changelog with all merged PRs (#341)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T04:42:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "48001279ee7807edc8d2bffba4640978b531510d",
"body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore: release v0.13.5 (#328)",
"author_name": "github-actions[bot]",
"author_login": "github-actions[bot]",
"committed_at": "2025-12-13T04:29:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "75bffb6ec25a49cb231418d2d816e3b8e3017d01",
"body": "MDBOOK002: Skip external doc links that go outside book source directory\n- Links like ../std/, ../reference/, ../nomicon/ resolve at runtime\n- Added is_external_doc_link() and normalize_path() helpers\n- Fixes #337\n\nCONTENT001: Require comment-style context for BUG marker\n- BUG in prose like 'this bu\n[…]\neceded by '.' (file extensions like .html, .json)\n- Fixes #339\n\nTested against The Rust Book:\n- MDBOOK002: 34 -> 0 violations\n- CONTENT001: 31 -> 2 violations (real TODOs)\n- MD044: 280 -> 8 violations",
"is_bot": false,
"headline": "fix: reduce false positives in MDBOOK002, CONTENT001, and MD044 (#340)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T04:25:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a68fb8a6feeae6337b02a23f174ea1931a9c49f7",
"body": "Add 'preprocessor' keyword and update description to mention preprocessor\nfunctionality. This helps users discover mdbook-lint when searching for\nmdBook preprocessors on crates.io.",
"is_bot": false,
"headline": "docs: add preprocessor to keywords and description (#336)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T04:00:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "73799f0815b5a9cc530a2d15cdad06c3b4fc9d4c",
"body": "…te variables (#335)\n\n- MD052: Add extended checkbox states to ignored labels ([-], [>], [<], [?], [!], [*], etc.)\n- MD052: Add wiki-link syntax detection ([[text]], ![[embed]])\n- MDBOOK010: Skip template variable syntax (${var}, ${env:HOME})",
"is_bot": false,
"headline": "fix: add support for extended checkbox states, wiki-links, and templa…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T03:42:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c45c184c5202b408940cbf272aa16e140c662500",
"body": "- MD052: Add space to ignored labels for task list checkboxes (- [ ])\n- MD052: Skip abbreviation definitions (*[ABBR]:) and inline footnotes (^[text])\n- MD030: Skip abbreviation definitions that start with *[\n- MDBOOK010: Skip lines where all dollar signs are currency amounts (00)",
"is_bot": false,
"headline": "fix: resolve false positives for extended markdown syntax (#334)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T03:30:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b205b3acaf82af5da2e0347b4bc5116b902aeb36",
"body": "* fix: support named anchors in MDBOOK008 and MDBOOK012\n\nUpdate both rules to recognize mdBook's named anchor syntax like\n:main, :example, :my_function in include directives.\n\nChanges:\n- MDBOOK012: Add is_valid_anchor_name() to accept identifier-like\n anchor names (letters, digits, underscores)\n- M\n[…]\nive markdown\ntest files. Specifically verify the KaTeX test file has zero errors\nas a regression test for math-related false positives.\n\n* test: add extended-features-test.md to comprehensive fixtures",
"is_bot": false,
"headline": "fix: support named anchors and add comprehensive test fixtures (#333)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T03:27:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7d79a5fad60a4f80842133fb3dc1a5707337fd4d",
"body": "Brackets in headings like '### Array[i] Notation' or\n'## Matrix[row][col] Access' were being incorrectly flagged as\nundefined reference links.\n\nAdd heading line detection to LinkParser:\n- Skip shortcut references (e.g., [i]) on heading lines entirely\n- Skip full reference patterns (e.g., [row][col]) on heading lines\n when both parts look like array indices (short alphanumeric strings)\n\nActual reference links in headings like '# See [docs][link]' are\nstill properly validated.",
"is_bot": false,
"headline": "fix: skip bracket patterns in headings for MD052 (#332)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T03:20:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "da8e4c8da1838eab9580c9c60dc5fe59d930eb52",
"body": "Lines starting with - inside display math blocks (like in \\begin{cases}\nenvironments) were incorrectly flagged as list markers with incorrect\nspacing.\n\nAdd display math block state tracking to skip content between $$...$$\ndelimiters, similar to how code blocks are already handled.\n\nFixes false positives for KaTeX expressions like:\n- $$f(x) = \\begin{cases} -x^2 & ... \\end{cases}$$",
"is_bot": false,
"headline": "fix: skip display math blocks in MD030 list marker detection (#331)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T03:11:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a0de494559ad8c99eece6ca8e5ad189b6771e9fb",
"body": "Add extensive test file for KaTeX/LaTeX math expressions covering:\n- Greek and Hebrew letters\n- Arrows (standard, special, extensible)\n- Accents and decorations\n- Delimiters (basic, auto-sizing, manual sizing)\n- Fractions, binomials, roots\n- Sums, products, integrals, limits\n- Binary operators and r\n[…]\ns, sizing, colors\n- Physics notation, chemical equations\n- Complex examples (Maxwell, Schrodinger, Navier-Stokes, etc.)\n- Edge cases and special scenarios\n\nRelated issues: #320, #321, #322, #323, #324",
"is_bot": false,
"headline": "test: add comprehensive KaTeX math test fixture (#330)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T03:11:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "de91c5cc749575afa992d2f3035febed5acbc018",
"body": "…#325)\n\nFixes #322\n\nWhen a link is followed by a footnote reference like [link](#title)[^footnote],\nMD011 was incorrectly detecting (#title)[^footnote] as reversed link syntax.\n\nThe fix checks if the bracket content starts with ^ (footnote marker) and\nskips detection in that case, since no valid URL starts with ^.\n\nAdded tests for:\n- Single footnote after link\n- Multiple footnotes after links\n- Numeric footnotes\n- Actual reversed links with ^ in URL still detected",
"is_bot": false,
"headline": "fix: exclude footnote references from MD011 reversed link detection (…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T02:52:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "266f7f695aa672dda8506a65a00d52dae270681b",
"body": "Fixes #323\nFixes #324\n\nUpdated slug generation in MD051 and CONTENT006 to match mdBook's actual\nslugification algorithm:\n\n- Preserve underscores (important for code identifiers like a_title)\n- Do NOT consolidate multiple consecutive hyphens (mdBook preserves them)\n- Replace all non-alphanumeric char\n[…]\n--title`\n- Headings like `## \\`a_title\\`` which preserve underscore as `a_title`\n\nRemoved unused consolidate_dashes() function from MD051.\n\nUpdated tests to reflect the new mdBook-compatible behavior.",
"is_bot": false,
"headline": "fix: align slug generation with mdBook behavior (#329)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T02:52:36Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "95997935353b5effeb093c5be8d248027725425d",
"body": "Fixes #321\n\nKaTeX expressions like $A[i][j]$ were being incorrectly flagged as\nundefined reference links. Added math block tracking to LinkParser:\n\n- Track in_inline_math state for $...$ blocks\n- Track in_display_math state for $$...$$ blocks\n- Skip link/image detection when inside math blocks\n- Han\n[…]\n\n\nAdded tests for:\n- Inline math with array syntax\n- Display math blocks\n- Complex KaTeX expressions\n- Escaped dollar signs\n- Multiple math blocks on one line\n- Math followed by actual reference links",
"is_bot": false,
"headline": "fix: skip link detection inside math blocks in MD052 (#327)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T02:47:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "299c2d21c11e88ed36322e63740b6bf6b9003559",
"body": "Fixes #320\n\nThe rule was counting all $ characters to detect unclosed math blocks,\nbut escaped \\$ should not count as delimiters. Added count_unescaped_dollars()\nhelper that properly handles escape sequences:\n- \\$ -> escaped (not a delimiter)\n- \\\\\\$ -> unescaped (backslash is escaped, $ is delimiter\n[…]\n backslashes + escaped dollar)\n\nAdded tests for:\n- Escaped dollar in KaTeX: $(\\$)$\n- Multiple escaped dollars\n- Mixed escaped/unescaped\n- Double backslash edge case\n- Direct helper function unit tests",
"is_bot": false,
"headline": "fix: handle escaped dollar signs in MDBOOK010 KaTeX validation (#326)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-13T02:45:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "addba2081b0065a11e2d575e54d3d9f79312b512",
"body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore: release v0.13.4 (#318)",
"author_name": "github-actions[bot]",
"author_login": "github-actions[bot]",
"committed_at": "2025-12-12T16:55:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a1731b8fe1122c3541a2df80a2751e303d2ab79f",
"body": "Previously, the preprocessor would only look for .mdbook-lint.toml if\nthere was no [preprocessor.lint] section in book.toml. This meant users\ncouldn't use both configuration sources together.\n\nNow the preprocessor follows this precedence order:\n1. Default configuration\n2. .mdbook-lint.toml file (if \n[…]\nghest precedence)\n\nThis allows users to maintain their lint configuration in a separate\n.mdbook-lint.toml file while still being able to override specific\nsettings in book.toml if needed.\n\nCloses #315",
"is_bot": false,
"headline": "fix: preprocessor now discovers .mdbook-lint.toml config files (#319)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-12T14:15:15Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0f34e786e615dff49d5e2fd301f76e3f55853891",
"body": "…rences (#317)\n\nGitHub-style admonitions like [!NOTE], [!TIP], [!IMPORTANT], [!WARNING],\nand [!CAUTION] are now ignored by default in MD052. These are supported\nby mdBook 0.5+ and should not be flagged as undefined reference links.\n\nCloses #314",
"is_bot": false,
"headline": "fix: MD052 no longer flags GitHub-style admonitions as undefined refe…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-12T14:14:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c29b0ec6eedb6ba126e4899035a8b53c220dc78d",
"body": "mdBook automatically prepends 'mdbook-' to preprocessor names, so\n[preprocessor.lint] invokes the 'mdbook-lint' command. Using\n[preprocessor.mdbook-lint] would incorrectly try to invoke\n'mdbook-mdbook-lint'.\n\nFixes the same issue across all documentation files.\n\nCloses #313",
"is_bot": false,
"headline": "docs: fix preprocessor naming from mdbook-lint to lint (#316)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-12T13:24:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "74a6bfd9984ec8c6ca5bd5061dadf9516d85354b",
"body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore: release v0.13.3 (#311)",
"author_name": "github-actions[bot]",
"author_login": "github-actions[bot]",
"committed_at": "2025-12-11T21:19:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7a34f6f52670411a8590c7f33cb1a72ecda1eb8b",
"body": "The rules/index.md file is the canonical location for rule documentation\nand is properly referenced in SUMMARY.md. The rules-reference.md file\nwas orphaned and duplicative.",
"is_bot": false,
"headline": "docs: remove orphaned rules-reference.md (#312)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-11T21:13:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2d7be72194f1ade426dc92ed56dd49194d761a0b",
"body": "- Add 'fix' subcommand as a shorthand for 'lint --fix'\n- Makes auto-fix functionality more discoverable in --help output\n- Supports all relevant options: --dry-run, --fix-unsafe, --no-backup, etc.\n- Update README to show fix subcommand as primary method\n- Add comprehensive tests for fix subcommand\n\nUsage:\n mdbook-lint fix src/*.md # Fix issues\n mdbook-lint fix --dry-run src/ # Preview fixes\n mdbook-lint fix --fix-unsafe src/ # Include unsafe fixes",
"is_bot": false,
"headline": "feat: add fix subcommand for easier auto-fix discoverability (#310)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-11T19:59:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "587349e7e9da28656a8aba84de819c0102992344",
"body": "- Add cliff.toml for git-cliff changelog configuration\n- Simplify release-plz.toml to use cliff.toml for changelog\n- Generate CHANGELOG.md from git history with proper formatting\n- Configure per-package changelog settings (only CLI package gets CHANGELOG.md)\n- Add CHANGELOG.md exception to .gitignor\n[…]\nouped commits by type (Features, Bug Fixes, Documentation, etc.)\n- Links to commits and pull requests\n- Proper version headings with dates\n\nThis fixes the empty release notes issue in recent releases.",
"is_bot": false,
"headline": "fix: enable changelog generation with git-cliff (#309)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-11T18:15:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c5656016d241262d91600999a3a6576ac37c76e1",
"body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore: release v0.13.2 (#306)",
"author_name": "github-actions[bot]",
"author_login": "github-actions[bot]",
"committed_at": "2025-12-11T17:15:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2408ce4a21f78d44b4b1968675cacfbed55dee84",
"body": "…(#308)\n\n- Add 'What is mdBook?' section to README explaining what mdBook is\n- Add Compatibility section to README with link to detailed docs\n- Create new compatibility.md page documenting:\n - mdBook 0.4.x and 0.5.x support\n - Automatic version detection and JSON protocol normalization\n - Platform support matrix\n - MSRV requirements\n - markdownlint compatibility notes\n - CI environment support",
"is_bot": false,
"headline": "docs: add mdbook explanation and version compatibility documentation …",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-11T16:59:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "05810783da50e643db3593e4bf9571a494b7c8d0",
"body": "mdbook 0.5.x introduced breaking changes to the preprocessor JSON format:\n1. Book::sections renamed to Book::items\n2. __non_exhaustive field removed from JSON output\n\nThis change adds JSON normalization that:\n- Converts 'items' back to 'sections' for mdbook 0.4.x type compatibility\n- Adds '__non_exh\n[…]\ne added for:\n- mdbook 0.4.x JSON format (sections, with __non_exhaustive)\n- mdbook 0.5.x JSON format (items, without __non_exhaustive)\n- Null value stripping\n- Nested object normalization\n\nCloses #304",
"is_bot": false,
"headline": "feat: add support for mdbook 0.5.x JSON format (#305)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-11T16:47:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2fc326f22ab55bc002d8cceef53a9407ef06a55c",
"body": "Adds a scheduled workflow that tests mdbook-lint against multiple mdbook\nversions to catch compatibility issues early.\n\nFeatures:\n- Tests mdbook 0.4.40, 0.4.52, 0.5.0, and 0.5.1\n- Runs weekly on Sundays at 00:00 UTC\n- Can be triggered manually via workflow_dispatch\n- Tests both preprocessor mode (md\n[…]\nifacts for debugging\n- Automatically creates an issue if scheduled run fails\n\nThis helps ensure we maintain compatibility across mdbook versions,\nespecially after the breaking changes in mdbook 0.5.x.",
"is_bot": false,
"headline": "ci: add mdbook compatibility matrix workflow (#307)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-11T16:44:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9688b10ce262ea7248345b88d3ac9866c148d561",
"body": "…#303)\n\nmdbook sends JSON with null values (e.g., \"description\": null) to\npreprocessors via stdin. However, mdbook's Config struct internally uses\ntoml::Value which doesn't support null values, causing deserialization\nto fail with: \"invalid type: null, expected any valid TOML value\"\n\nThis fix:\n- Par\n[…]\n\n- Adds unit tests for the null stripping logic\n\nNote: This fix is for mdbook 0.4.x. Support for mdbook 0.5.x (which\nchanged 'sections' to 'items' in the Book JSON) will be addressed in\na separate PR.",
"is_bot": false,
"headline": "fix: strip null values from mdbook JSON to fix TOML deserialization (…",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-11T16:37:40Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a7de4c26f843f337a7e45b66fcc6120633ef45bb",
"body": null,
"is_bot": false,
"headline": "docs: remove duplicate sections from contributing guide (#302)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-11T16:18:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7cf1fe02562ed568e81ce5419271a835f912394b",
"body": "Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore: release v0.13.1 (#297)",
"author_name": "github-actions[bot]",
"author_login": "github-actions[bot]",
"committed_at": "2025-12-07T15:32:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "16ea9971760243948a900ecb647854ec09097f29",
"body": "Configure git-cliff style changelog generation directly in release-plz.toml\nusing the integrated [changelog] section. This groups commits by type\n(feat, fix, docs, etc.) for cleaner release notes.\n\nCommit parsers:\n- Features (feat)\n- Bug Fixes (fix)\n- Documentation (doc/docs)\n- Performance (perf)\n- Refactor (refactor)\n- Styling (style)\n- Testing (test)\n- Miscellaneous (chore)\n\nSkips release chore commits to avoid noise in changelogs.",
"is_bot": false,
"headline": "chore: add changelog configuration for release-plz (#299)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-06T04:48:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dda8d8037f5304569143f5453ad9f52b368a4813",
"body": "- Update README with accurate counts (55 standard + 18 mdBook + 10 content)\n- Update rules-reference.md with new CONTENT006-011 rules\n- Update introduction.md, installation.md, api-documentation.md, configuration.md",
"is_bot": false,
"headline": "docs: update rule counts to 83 (10 content rules) (#298)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-06T04:38:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e20d5e0157dc8391109416c9963b643810faa304",
"body": "- CONTENT006: no-broken-internal-links - validates internal anchor links\n- CONTENT007: consistent-terminology - detects inconsistent term usage\n- CONTENT009: no-excessive-nesting - warns on deep heading hierarchies\n- CONTENT010: link-text-quality - flags generic link text like 'click here'\n- CONTENT011: no-future-tense - encourages present tense in documentation",
"is_bot": false,
"headline": "feat: add five new content quality rules (#296)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-06T04:29:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "122876877442cfd4fa06668196433084f84b99c2",
"body": "- Add -v/--verbose global flag to show config path being used\n- Add -q/--quiet global flag to suppress informational messages\n- Add cargo-style colored help output (yellow headers, cyan literals)\n- Remove debug output from config discovery and preprocessor\n- Add print_status() helper for cargo-style status messages\n- Update print_summary() to respect quiet mode\n\nThe flags and styling follow cargo's CLI patterns for consistent UX.",
"is_bot": false,
"headline": "feat: add verbose and quiet CLI flags with colored help (#295)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-05T23:17:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b6da5808d47d671853430678217805053aadc59a",
"body": "* fix: enable content feature by default in CLI\n\nThe content rules (CONTENT001-005) are now included by default when\ninstalling mdbook-lint, matching the rulesets crate's default features.\n\n* chore: add root config and lint top-level markdown files\n\n- Add .mdbook-lint.toml for project documentation \n[…]\n MDBOOK001 in root config\n\nMDBOOK001 was being inherited by integration tests and causing them\nto fail. MD040 provides the same check for project docs without\naffecting tests that depend on MDBOOK001.",
"is_bot": false,
"headline": "fix: enable content feature by default in CLI (#293)",
"author_name": "Josh Rotenberg",
"author_login": "joshrotenberg",
"committed_at": "2025-12-05T19:00:28Z",
"body_truncated": true,
"is_coding_agent": false
}
],
"releases_count": 31,
"commits_last_year": 277,
"latest_release_at": "2026-07-27T23:10:23Z",
"latest_release_tag": "v0.15.0",
"releases_from_tags": false,
"days_since_last_push": 1,
"active_weeks_last_year": 16,
"days_since_latest_release": 1,
"mean_days_between_releases": 25.3
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 57,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "mdbook-lint",
"exists": true,
"license": "MIT OR Apache-2.0",
"keywords": [
"documentation",
"linter",
"markdown",
"mdbook",
"preprocessor",
"development-tools",
"command-line-utilities"
],
"ecosystem": "crates",
"matches_repo": true,
"registry_url": "https://crates.io/crates/mdbook-lint",
"is_deprecated": false,
"latest_version": "0.15.0",
"repository_url": "https://github.com/joshrotenberg/mdbook-lint",
"versions_count": 29,
"total_downloads": 5488,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 146,
"first_published_at": "2025-08-04T01:37:48.328569Z",
"latest_published_at": "2026-07-27T23:05:38.517367Z",
"latest_version_yanked": false,
"days_since_latest_publish": 1
},
{
"name": "mdbook-lint-core",
"exists": true,
"license": "MIT OR Apache-2.0",
"keywords": [
"documentation",
"library",
"linter",
"markdown",
"mdbook",
"development-tools",
"text-processing"
],
"ecosystem": "crates",
"matches_repo": true,
"registry_url": "https://crates.io/crates/mdbook-lint-core",
"is_deprecated": false,
"latest_version": "0.15.0",
"repository_url": "https://github.com/joshrotenberg/mdbook-lint",
"versions_count": 27,
"total_downloads": 12878,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 2338,
"first_published_at": "2025-08-15T17:57:44.477903Z",
"latest_published_at": "2026-07-27T23:04:56.900453Z",
"latest_version_yanked": false,
"days_since_latest_publish": 1
},
{
"name": "mdbook-lint-rulesets",
"exists": true,
"license": "MIT OR Apache-2.0",
"keywords": [
"linter",
"markdown",
"mdbook",
"rules",
"rulesets",
"development-tools",
"text-processing"
],
"ecosystem": "crates",
"matches_repo": true,
"registry_url": "https://crates.io/crates/mdbook-lint-rulesets",
"is_deprecated": false,
"latest_version": "0.15.0",
"repository_url": "https://github.com/joshrotenberg/mdbook-lint",
"versions_count": 27,
"total_downloads": 12528,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 2331,
"first_published_at": "2025-08-15T17:58:03.916213Z",
"latest_published_at": "2026-07-27T23:05:02.571838Z",
"latest_version_yanked": false,
"days_since_latest_publish": 1
}
]
},
"popularity": {
"forks": 3,
"stars": 27,
"watchers": 0,
"fork_history": {
"days": [
{
"date": "2025-12-04",
"count": 1
},
{
"date": "2025-12-29",
"count": 1
},
{
"date": "2026-05-22",
"count": 1
}
],
"complete": true,
"collected": 3,
"total_forks": 3
},
"star_history": null,
"open_issues_and_prs": 7
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"Cargo.toml",
"crates/mdbook-lint-cli/Cargo.toml",
"crates/mdbook-lint-core/Cargo.toml",
"crates/mdbook-lint-rulesets/Cargo.toml"
],
"largest_source_bytes": 84284,
"source_files_sampled": 146,
"oversized_source_files": 1,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"Cargo.toml"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "proc-macro-error2",
"direct": false,
"version": "2.0.1",
"severity": "unknown",
"ecosystem": "crates",
"cvss_score": null,
"advisory_ids": [
"RUSTSEC-2026-0173"
],
"fixed_version": null,
"advisory_count": 1,
"oldest_advisory_days": 51
}
],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {
"unknown": 1
},
"advisory_count": 1,
"affected_count": 1,
"assessed_count": 293,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 8,
"direct_affected_count": 0
},
"ecosystems": [
"crates"
],
"dependencies": [
{
"name": "anyhow",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "thiserror",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde_json",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde_yaml",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "toml",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "comrak",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "clap",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "mdbook",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "walkdir",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "glob",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "rayon",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.10"
},
{
"name": "tabled",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.20"
},
{
"name": "anstream",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.6"
},
{
"name": "anstyle",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.0"
},
{
"name": "tower-lsp",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "0.20"
},
{
"name": "tokio",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.0"
},
{
"name": "mdbook-lint-core",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "mdbook-lint-rulesets",
"manifest": "crates/mdbook-lint-cli/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "anyhow",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "thiserror",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde_json",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde_yaml",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "toml",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "comrak",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "mdbook",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "walkdir",
"manifest": "crates/mdbook-lint-core/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "mdbook-lint-core",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "anyhow",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "thiserror",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde_json",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "comrak",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "mdbook",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "serde_yaml",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "walkdir",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "glob",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
},
{
"name": "regex",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": "1.10"
},
{
"name": "toml",
"manifest": "crates/mdbook-lint-rulesets/Cargo.toml",
"ecosystem": "crates",
"version_constraint": null
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "anstream",
"direct": true,
"version": null,
"ecosystem": "crates"
},
{
"name": "anstream",
"direct": true,
"version": "0.6.20",
"ecosystem": "crates"
},
{
"name": "anstyle",
"direct": true,
"version": null,
"ecosystem": "crates"
},
{
"name": "anstyle",
"direct": true,
"version": "1.0.11",
"ecosystem": "crates"
},
{
"name": "anyhow",
"direct": true,
"version": "1.0.103",
"ecosystem": "crates"
},
{
"name": "clap",
"direct": true,
"version": "4.5.46",
"ecosystem": "crates"
},
{
"name": "comrak",
"direct": true,
"version": "0.21.0",
"ecosystem": "crates"
},
{
"name": "glob",
"direct": true,
"version": "0.3.3",
"ecosystem": "crates"
},
{
"name": "mdbook",
"direct": true,
"version": "0.4.52",
"ecosystem": "crates"
},
{
"name": "rayon",
"direct": true,
"version": null,
"ecosystem": "crates"
},
{
"name": "rayon",
"direct": true,
"version": "1.11.0",
"ecosystem": "crates"
},
{
"name": "regex",
"direct": true,
"version": null,
"ecosystem": "crates"
},
{
"name": "regex",
"direct": true,
"version": "1.11.2",
"ecosystem": "crates"
},
{
"name": "serde",
"direct": true,
"version": "1.0.228",
"ecosystem": "crates"
},
{
"name": "serde_json",
"direct": true,
"version": "1.0.143",
"ecosystem": "crates"
},
{
"name": "serde_yaml",
"direct": true,
"version": "0.9.34+deprecated",
"ecosystem": "crates"
},
{
"name": "tabled",
"direct": true,
"version": null,
"ecosystem": "crates"
},
{
"name": "tabled",
"direct": true,
"version": "0.20.0",
"ecosystem": "crates"
},
{
"name": "thiserror",
"direct": true,
"version": "1.0.69",
"ecosystem": "crates"
},
{
"name": "thiserror",
"direct": true,
"version": "2.0.16",
"ecosystem": "crates"
},
{
"name": "tokio",
"direct": true,
"version": null,
"ecosystem": "crates"
},
{
"name": "tokio",
"direct": true,
"version": "1.47.1",
"ecosystem": "crates"
},
{
"name": "toml",
"direct": true,
"version": "0.5.11",
"ecosystem": "crates"
},
{
"name": "tower-lsp",
"direct": true,
"version": null,
"ecosystem": "crates"
},
{
"name": "tower-lsp",
"direct": true,
"version": "0.20.0",
"ecosystem": "crates"
},
{
"name": "walkdir",
"direct": true,
"version": "2.5.0",
"ecosystem": "crates"
},
{
"name": "addr2line",
"direct": false,
"version": "0.24.2",
"ecosystem": "crates"
},
{
"name": "adler2",
"direct": false,
"version": "2.0.1",
"ecosystem": "crates"
},
{
"name": "aho-corasick",
"direct": false,
"version": "1.1.3",
"ecosystem": "crates"
},
{
"name": "android-tzdata",
"direct": false,
"version": "0.1.1",
"ecosystem": "crates"
},
{
"name": "android_system_properties",
"direct": false,
"version": "0.1.5",
"ecosystem": "crates"
},
{
"name": "anes",
"direct": false,
"version": "0.1.6",
"ecosystem": "crates"
},
{
"name": "anstyle-parse",
"direct": false,
"version": "0.2.7",
"ecosystem": "crates"
},
{
"name": "anstyle-query",
"direct": false,
"version": "1.1.4",
"ecosystem": "crates"
},
{
"name": "anstyle-wincon",
"direct": false,
"version": "3.0.10",
"ecosystem": "crates"
},
{
"name": "assert_cmd",
"direct": false,
"version": "2.0.17",
"ecosystem": "crates"
},
{
"name": "async-trait",
"direct": false,
"version": "0.1.89",
"ecosystem": "crates"
},
{
"name": "auto_impl",
"direct": false,
"version": "1.3.0",
"ecosystem": "crates"
},
{
"name": "autocfg",
"direct": false,
"version": "1.5.0",
"ecosystem": "crates"
},
{
"name": "backtrace",
"direct": false,
"version": "0.3.75",
"ecosystem": "crates"
},
{
"name": "bit-set",
"direct": false,
"version": "0.8.0",
"ecosystem": "crates"
},
{
"name": "bit-vec",
"direct": false,
"version": "0.8.0",
"ecosystem": "crates"
},
{
"name": "bitflags",
"direct": false,
"version": "1.3.2",
"ecosystem": "crates"
},
{
"name": "bitflags",
"direct": false,
"version": "2.9.3",
"ecosystem": "crates"
},
{
"name": "block-buffer",
"direct": false,
"version": "0.10.4",
"ecosystem": "crates"
},
{
"name": "bstr",
"direct": false,
"version": "1.12.0",
"ecosystem": "crates"
},
{
"name": "bumpalo",
"direct": false,
"version": "3.19.0",
"ecosystem": "crates"
},
{
"name": "bytecount",
"direct": false,
"version": "0.6.9",
"ecosystem": "crates"
},
{
"name": "bytes",
"direct": false,
"version": "1.11.1",
"ecosystem": "crates"
},
{
"name": "cast",
"direct": false,
"version": "0.3.0",
"ecosystem": "crates"
},
{
"name": "cc",
"direct": false,
"version": "1.2.34",
"ecosystem": "crates"
},
{
"name": "cfg-if",
"direct": false,
"version": "1.0.3",
"ecosystem": "crates"
},
{
"name": "chrono",
"direct": false,
"version": "0.4.41",
"ecosystem": "crates"
},
{
"name": "ciborium",
"direct": false,
"version": "0.2.2",
"ecosystem": "crates"
},
{
"name": "ciborium-io",
"direct": false,
"version": "0.2.2",
"ecosystem": "crates"
},
{
"name": "ciborium-ll",
"direct": false,
"version": "0.2.2",
"ecosystem": "crates"
},
{
"name": "clap_builder",
"direct": false,
"version": "4.5.46",
"ecosystem": "crates"
},
{
"name": "clap_complete",
"direct": false,
"version": "4.5.57",
"ecosystem": "crates"
},
{
"name": "clap_derive",
"direct": false,
"version": "4.5.45",
"ecosystem": "crates"
},
{
"name": "clap_lex",
"direct": false,
"version": "0.7.5",
"ecosystem": "crates"
},
{
"name": "colorchoice",
"direct": false,
"version": "1.0.4",
"ecosystem": "crates"
},
{
"name": "core-foundation-sys",
"direct": false,
"version": "0.8.7",
"ecosystem": "crates"
},
{
"name": "cpufeatures",
"direct": false,
"version": "0.2.17",
"ecosystem": "crates"
},
{
"name": "criterion",
"direct": false,
"version": "0.5.1",
"ecosystem": "crates"
},
{
"name": "criterion-plot",
"direct": false,
"version": "0.5.0",
"ecosystem": "crates"
},
{
"name": "crossbeam-deque",
"direct": false,
"version": "0.8.6",
"ecosystem": "crates"
},
{
"name": "crossbeam-epoch",
"direct": false,
"version": "0.9.20",
"ecosystem": "crates"
},
{
"name": "crossbeam-utils",
"direct": false,
"version": "0.8.21",
"ecosystem": "crates"
},
{
"name": "crunchy",
"direct": false,
"version": "0.2.4",
"ecosystem": "crates"
},
{
"name": "crypto-common",
"direct": false,
"version": "0.1.6",
"ecosystem": "crates"
},
{
"name": "darling",
"direct": false,
"version": "0.14.4",
"ecosystem": "crates"
},
{
"name": "darling",
"direct": false,
"version": "0.20.11",
"ecosystem": "crates"
},
{
"name": "darling_core",
"direct": false,
"version": "0.14.4",
"ecosystem": "crates"
},
{
"name": "darling_core",
"direct": false,
"version": "0.20.11",
"ecosystem": "crates"
},
{
"name": "darling_macro",
"direct": false,
"version": "0.14.4",
"ecosystem": "crates"
},
{
"name": "darling_macro",
"direct": false,
"version": "0.20.11",
"ecosystem": "crates"
},
{
"name": "dashmap",
"direct": false,
"version": "5.5.3",
"ecosystem": "crates"
},
{
"name": "derive_builder",
"direct": false,
"version": "0.12.0",
"ecosystem": "crates"
},
{
"name": "derive_builder",
"direct": false,
"version": "0.20.2",
"ecosystem": "crates"
},
{
"name": "derive_builder_core",
"direct": false,
"version": "0.12.0",
"ecosystem": "crates"
},
{
"name": "derive_builder_core",
"direct": false,
"version": "0.20.2",
"ecosystem": "crates"
},
{
"name": "derive_builder_macro",
"direct": false,
"version": "0.12.0",
"ecosystem": "crates"
},
{
"name": "derive_builder_macro",
"direct": false,
"version": "0.20.2",
"ecosystem": "crates"
},
{
"name": "deunicode",
"direct": false,
"version": "1.6.2",
"ecosystem": "crates"
},
{
"name": "difflib",
"direct": false,
"version": "0.4.0",
"ecosystem": "crates"
},
{
"name": "digest",
"direct": false,
"version": "0.10.7",
"ecosystem": "crates"
},
{
"name": "displaydoc",
"direct": false,
"version": "0.2.5",
"ecosystem": "crates"
},
{
"name": "doc-comment",
"direct": false,
"version": "0.3.3",
"ecosystem": "crates"
},
{
"name": "either",
"direct": false,
"version": "1.15.0",
"ecosystem": "crates"
},
{
"name": "entities",
"direct": false,
"version": "1.0.1",
"ecosystem": "crates"
},
{
"name": "env_filter",
"direct": false,
"version": "0.1.3",
"ecosystem": "crates"
},
{
"name": "env_logger",
"direct": false,
"version": "0.11.8",
"ecosystem": "crates"
},
{
"name": "equivalent",
"direct": false,
"version": "1.0.2",
"ecosystem": "crates"
},
{
"name": "errno",
"direct": false,
"version": "0.3.13",
"ecosystem": "crates"
},
{
"name": "fastrand",
"direct": false,
"version": "2.3.0",
"ecosystem": "crates"
},
{
"name": "float-cmp",
"direct": false,
"version": "0.10.0",
"ecosystem": "crates"
},
{
"name": "fnv",
"direct": false,
"version": "1.0.7",
"ecosystem": "crates"
},
{
"name": "form_urlencoded",
"direct": false,
"version": "1.2.2",
"ecosystem": "crates"
},
{
"name": "futures",
"direct": false,
"version": "0.3.31",
"ecosystem": "crates"
},
{
"name": "futures-channel",
"direct": false,
"version": "0.3.31",
"ecosystem": "crates"
},
{
"name": "futures-core",
"direct": false,
"version": "0.3.31",
"ecosystem": "crates"
},
{
"name": "futures-io",
"direct": false,
"version": "0.3.31",
"ecosystem": "crates"
},
{
"name": "futures-macro",
"direct": false,
"version": "0.3.31",
"ecosystem": "crates"
},
{
"name": "futures-sink",
"direct": false,
"version": "0.3.31",
"ecosystem": "crates"
},
{
"name": "futures-task",
"direct": false,
"version": "0.3.31",
"ecosystem": "crates"
},
{
"name": "futures-util",
"direct": false,
"version": "0.3.31",
"ecosystem": "crates"
},
{
"name": "generic-array",
"direct": false,
"version": "0.14.7",
"ecosystem": "crates"
},
{
"name": "getrandom",
"direct": false,
"version": "0.3.3",
"ecosystem": "crates"
},
{
"name": "gimli",
"direct": false,
"version": "0.31.1",
"ecosystem": "crates"
},
{
"name": "half",
"direct": false,
"version": "2.6.0",
"ecosystem": "crates"
},
{
"name": "handlebars",
"direct": false,
"version": "6.3.2",
"ecosystem": "crates"
},
{
"name": "hashbrown",
"direct": false,
"version": "0.14.5",
"ecosystem": "crates"
},
{
"name": "hashbrown",
"direct": false,
"version": "0.15.5",
"ecosystem": "crates"
},
{
"name": "heck",
"direct": false,
"version": "0.5.0",
"ecosystem": "crates"
},
{
"name": "hermit-abi",
"direct": false,
"version": "0.5.2",
"ecosystem": "crates"
},
{
"name": "hex",
"direct": false,
"version": "0.4.3",
"ecosystem": "crates"
},
{
"name": "home",
"direct": false,
"version": "0.5.11",
"ecosystem": "crates"
},
{
"name": "httparse",
"direct": false,
"version": "1.10.1",
"ecosystem": "crates"
},
{
"name": "iana-time-zone",
"direct": false,
"version": "0.1.63",
"ecosystem": "crates"
},
{
"name": "iana-time-zone-haiku",
"direct": false,
"version": "0.1.2",
"ecosystem": "crates"
},
{
"name": "icu_collections",
"direct": false,
"version": "2.0.0",
"ecosystem": "crates"
},
{
"name": "icu_locale_core",
"direct": false,
"version": "2.0.0",
"ecosystem": "crates"
},
{
"name": "icu_normalizer",
"direct": false,
"version": "2.0.0",
"ecosystem": "crates"
},
{
"name": "icu_normalizer_data",
"direct": false,
"version": "2.0.0",
"ecosystem": "crates"
},
{
"name": "icu_properties",
"direct": false,
"version": "2.0.1",
"ecosystem": "crates"
},
{
"name": "icu_properties_data",
"direct": false,
"version": "2.0.1",
"ecosystem": "crates"
},
{
"name": "icu_provider",
"direct": false,
"version": "2.0.0",
"ecosystem": "crates"
},
{
"name": "ident_case",
"direct": false,
"version": "1.0.1",
"ecosystem": "crates"
},
{
"name": "idna",
"direct": false,
"version": "1.1.0",
"ecosystem": "crates"
},
{
"name": "idna_adapter",
"direct": false,
"version": "1.2.1",
"ecosystem": "crates"
},
{
"name": "indexmap",
"direct": false,
"version": "2.11.0",
"ecosystem": "crates"
},
{
"name": "io-uring",
"direct": false,
"version": "0.7.10",
"ecosystem": "crates"
},
{
"name": "is-terminal",
"direct": false,
"version": "0.4.16",
"ecosystem": "crates"
},
{
"name": "is_terminal_polyfill",
"direct": false,
"version": "1.70.1",
"ecosystem": "crates"
},
{
"name": "itertools",
"direct": false,
"version": "0.10.5",
"ecosystem": "crates"
},
{
"name": "itoa",
"direct": false,
"version": "1.0.15",
"ecosystem": "crates"
},
{
"name": "jiff",
"direct": false,
"version": "0.2.15",
"ecosystem": "crates"
},
{
"name": "jiff-static",
"direct": false,
"version": "0.2.15",
"ecosystem": "crates"
},
{
"name": "js-sys",
"direct": false,
"version": "0.3.77",
"ecosystem": "crates"
},
{
"name": "libc",
"direct": false,
"version": "0.2.175",
"ecosystem": "crates"
},
{
"name": "linux-raw-sys",
"direct": false,
"version": "0.4.15",
"ecosystem": "crates"
},
{
"name": "linux-raw-sys",
"direct": false,
"version": "0.9.4",
"ecosystem": "crates"
},
{
"name": "litemap",
"direct": false,
"version": "0.8.0",
"ecosystem": "crates"
},
{
"name": "lock_api",
"direct": false,
"version": "0.4.13",
"ecosystem": "crates"
},
{
"name": "log",
"direct": false,
"version": "0.4.27",
"ecosystem": "crates"
},
{
"name": "lsp-types",
"direct": false,
"version": "0.94.1",
"ecosystem": "crates"
},
{
"name": "memchr",
"direct": false,
"version": "2.7.5",
"ecosystem": "crates"
},
{
"name": "miniz_oxide",
"direct": false,
"version": "0.8.9",
"ecosystem": "crates"
},
{
"name": "mio",
"direct": false,
"version": "1.0.4",
"ecosystem": "crates"
},
{
"name": "normalize-line-endings",
"direct": false,
"version": "0.3.0",
"ecosystem": "crates"
},
{
"name": "normpath",
"direct": false,
"version": "1.3.0",
"ecosystem": "crates"
},
{
"name": "num-modular",
"direct": false,
"version": "0.6.1",
"ecosystem": "crates"
},
{
"name": "num-order",
"direct": false,
"version": "1.2.0",
"ecosystem": "crates"
},
{
"name": "num-traits",
"direct": false,
"version": "0.2.19",
"ecosystem": "crates"
},
{
"name": "object",
"direct": false,
"version": "0.36.7",
"ecosystem": "crates"
},
{
"name": "once_cell",
"direct": false,
"version": "1.21.3",
"ecosystem": "crates"
},
{
"name": "once_cell_polyfill",
"direct": false,
"version": "1.70.1",
"ecosystem": "crates"
},
{
"name": "oorandom",
"direct": false,
"version": "11.1.5",
"ecosystem": "crates"
},
{
"name": "opener",
"direct": false,
"version": "0.8.2",
"ecosystem": "crates"
},
{
"name": "papergrid",
"direct": false,
"version": "0.17.0",
"ecosystem": "crates"
},
{
"name": "parking_lot_core",
"direct": false,
"version": "0.9.11",
"ecosystem": "crates"
},
{
"name": "percent-encoding",
"direct": false,
"version": "2.3.2",
"ecosystem": "crates"
},
{
"name": "pest",
"direct": false,
"version": "2.8.1",
"ecosystem": "crates"
},
{
"name": "pest_derive",
"direct": false,
"version": "2.8.1",
"ecosystem": "crates"
},
{
"name": "pest_generator",
"direct": false,
"version": "2.8.1",
"ecosystem": "crates"
},
{
"name": "pest_meta",
"direct": false,
"version": "2.8.1",
"ecosystem": "crates"
},
{
"name": "pin-project",
"direct": false,
"version": "1.1.10",
"ecosystem": "crates"
},
{
"name": "pin-project-internal",
"direct": false,
"version": "1.1.10",
"ecosystem": "crates"
},
{
"name": "pin-project-lite",
"direct": false,
"version": "0.2.16",
"ecosystem": "crates"
},
{
"name": "pin-utils",
"direct": false,
"version": "0.1.0",
"ecosystem": "crates"
},
{
"name": "plotters",
"direct": false,
"version": "0.3.7",
"ecosystem": "crates"
},
{
"name": "plotters-backend",
"direct": false,
"version": "0.3.7",
"ecosystem": "crates"
},
{
"name": "plotters-svg",
"direct": false,
"version": "0.3.7",
"ecosystem": "crates"
},
{
"name": "portable-atomic",
"direct": false,
"version": "1.11.1",
"ecosystem": "crates"
},
{
"name": "portable-atomic-util",
"direct": false,
"version": "0.2.4",
"ecosystem": "crates"
},
{
"name": "potential_utf",
"direct": false,
"version": "0.1.3",
"ecosystem": "crates"
},
{
"name": "ppv-lite86",
"direct": false,
"version": "0.2.21",
"ecosystem": "crates"
},
{
"name": "predicates",
"direct": false,
"version": "3.1.3",
"ecosystem": "crates"
},
{
"name": "predicates-core",
"direct": false,
"version": "1.0.9",
"ecosystem": "crates"
},
{
"name": "predicates-tree",
"direct": false,
"version": "1.0.12",
"ecosystem": "crates"
},
{
"name": "proc-macro-error-attr2",
"direct": false,
"version": "2.0.0",
"ecosystem": "crates"
},
{
"name": "proc-macro-error2",
"direct": false,
"version": "2.0.1",
"ecosystem": "crates"
},
{
"name": "proc-macro2",
"direct": false,
"version": "1.0.101",
"ecosystem": "crates"
},
{
"name": "proptest",
"direct": false,
"version": null,
"ecosystem": "crates"
},
{
"name": "proptest",
"direct": false,
"version": "1.9.0",
"ecosystem": "crates"
},
{
"name": "pulldown-cmark",
"direct": false,
"version": "0.10.3",
"ecosystem": "crates"
},
{
"name": "pulldown-cmark-escape",
"direct": false,
"version": "0.10.1",
"ecosystem": "crates"
},
{
"name": "quick-error",
"direct": false,
"version": "1.2.3",
"ecosystem": "crates"
},
{
"name": "quote",
"direct": false,
"version": "1.0.40",
"ecosystem": "crates"
},
{
"name": "r-efi",
"direct": false,
"version": "5.3.0",
"ecosystem": "crates"
},
{
"name": "rand",
"direct": false,
"version": "0.9.4",
"ecosystem": "crates"
},
{
"name": "rand_chacha",
"direct": false,
"version": "0.9.0",
"ecosystem": "crates"
},
{
"name": "rand_core",
"direct": false,
"version": "0.9.5",
"ecosystem": "crates"
},
{
"name": "rand_xorshift",
"direct": false,
"version": "0.4.0",
"ecosystem": "crates"
},
{
"name": "rayon-core",
"direct": false,
"version": "1.13.0",
"ecosystem": "crates"
},
{
"name": "redox_syscall",
"direct": false,
"version": "0.5.17",
"ecosystem": "crates"
},
{
"name": "regex-automata",
"direct": false,
"version": "0.4.10",
"ecosystem": "crates"
},
{
"name": "regex-syntax",
"direct": false,
"version": "0.8.6",
"ecosystem": "crates"
},
{
"name": "rustc-demangle",
"direct": false,
"version": "0.1.26",
"ecosystem": "crates"
},
{
"name": "rustix",
"direct": false,
"version": "0.38.44",
"ecosystem": "crates"
},
{
"name": "rustix",
"direct": false,
"version": "1.0.8",
"ecosystem": "crates"
},
{
"name": "rustversion",
"direct": false,
"version": "1.0.22",
"ecosystem": "crates"
},
{
"name": "rusty-fork",
"direct": false,
"version": "0.3.1",
"ecosystem": "crates"
},
{
"name": "ryu",
"direct": false,
"version": "1.0.20",
"ecosystem": "crates"
},
{
"name": "same-file",
"direct": false,
"version": "1.0.6",
"ecosystem": "crates"
},
{
"name": "scopeguard",
"direct": false,
"version": "1.2.0",
"ecosystem": "crates"
},
{
"name": "serde_core",
"direct": false,
"version": "1.0.228",
"ecosystem": "crates"
},
{
"name": "serde_derive",
"direct": false,
"version": "1.0.228",
"ecosystem": "crates"
},
{
"name": "serde_repr",
"direct": false,
"version": "0.1.20",
"ecosystem": "crates"
},
{
"name": "sha2",
"direct": false,
"version": "0.10.9",
"ecosystem": "crates"
},
{
"name": "shlex",
"direct": false,
"version": "1.3.0",
"ecosystem": "crates"
},
{
"name": "slab",
"direct": false,
"version": "0.4.11",
"ecosystem": "crates"
},
{
"name": "slug",
"direct": false,
"version": "0.1.6",
"ecosystem": "crates"
},
{
"name": "smallvec",
"direct": false,
"version": "1.15.1",
"ecosystem": "crates"
},
{
"name": "socket2",
"direct": false,
"version": "0.6.0",
"ecosystem": "crates"
},
{
"name": "stable_deref_trait",
"direct": false,
"version": "1.2.0",
"ecosystem": "crates"
},
{
"name": "strsim",
"direct": false,
"version": "0.10.0",
"ecosystem": "crates"
},
{
"name": "strsim",
"direct": false,
"version": "0.11.1",
"ecosystem": "crates"
},
{
"name": "syn",
"direct": false,
"version": "1.0.109",
"ecosystem": "crates"
},
{
"name": "syn",
"direct": false,
"version": "2.0.106",
"ecosystem": "crates"
},
{
"name": "synstructure",
"direct": false,
"version": "0.13.2",
"ecosystem": "crates"
},
{
"name": "tabled_derive",
"direct": false,
"version": "0.11.0",
"ecosystem": "crates"
},
{
"name": "tempfile",
"direct": false,
"version": "3.21.0",
"ecosystem": "crates"
},
{
"name": "terminal_size",
"direct": false,
"version": "0.4.3",
"ecosystem": "crates"
},
{
"name": "termtree",
"direct": false,
"version": "0.5.1",
"ecosystem": "crates"
},
{
"name": "testing_table",
"direct": false,
"version": "0.3.0",
"ecosystem": "crates"
},
{
"name": "thiserror-impl",
"direct": false,
"version": "1.0.69",
"ecosystem": "crates"
},
{
"name": "thiserror-impl",
"direct": false,
"version": "2.0.16",
"ecosystem": "crates"
},
{
"name": "tinystr",
"direct": false,
"version": "0.8.1",
"ecosystem": "crates"
},
{
"name": "tinytemplate",
"direct": false,
"version": "1.2.1",
"ecosystem": "crates"
},
{
"name": "tokio-macros",
"direct": false,
"version": "2.5.0",
"ecosystem": "crates"
},
{
"name": "tokio-util",
"direct": false,
"version": "0.7.16",
"ecosystem": "crates"
},
{
"name": "topological-sort",
"direct": false,
"version": "0.2.2",
"ecosystem": "crates"
},
{
"name": "tower",
"direct": false,
"version": "0.4.13",
"ecosystem": "crates"
},
{
"name": "tower-layer",
"direct": false,
"version": "0.3.3",
"ecosystem": "crates"
},
{
"name": "tower-lsp-macros",
"direct": false,
"version": "0.9.0",
"ecosystem": "crates"
},
{
"name": "tower-service",
"direct": false,
"version": "0.3.3",
"ecosystem": "crates"
},
{
"name": "tracing",
"direct": false,
"version": "0.1.41",
"ecosystem": "crates"
},
{
"name": "tracing-attributes",
"direct": false,
"version": "0.1.30",
"ecosystem": "crates"
},
{
"name": "tracing-core",
"direct": false,
"version": "0.1.34",
"ecosystem": "crates"
},
{
"name": "typed-arena",
"direct": false,
"version": "2.0.2",
"ecosystem": "crates"
},
{
"name": "typenum",
"direct": false,
"version": "1.18.0",
"ecosystem": "crates"
},
{
"name": "ucd-trie",
"direct": false,
"version": "0.1.7",
"ecosystem": "crates"
},
{
"name": "unarray",
"direct": false,
"version": "0.1.4",
"ecosystem": "crates"
},
{
"name": "unicase",
"direct": false,
"version": "2.8.1",
"ecosystem": "crates"
},
{
"name": "unicode-ident",
"direct": false,
"version": "1.0.18",
"ecosystem": "crates"
},
{
"name": "unicode-width",
"direct": false,
"version": "0.2.2",
"ecosystem": "crates"
},
{
"name": "unicode_categories",
"direct": false,
"version": "0.1.1",
"ecosystem": "crates"
},
{
"name": "unsafe-libyaml",
"direct": false,
"version": "0.2.11",
"ecosystem": "crates"
},
{
"name": "url",
"direct": false,
"version": "2.5.7",
"ecosystem": "crates"
},
{
"name": "utf8_iter",
"direct": false,
"version": "1.0.4",
"ecosystem": "crates"
},
{
"name": "utf8parse",
"direct": false,
"version": "0.2.2",
"ecosystem": "crates"
},
{
"name": "version_check",
"direct": false,
"version": "0.9.5",
"ecosystem": "crates"
},
{
"name": "wait-timeout",
"direct": false,
"version": "0.2.1",
"ecosystem": "crates"
},
{
"name": "wasi",
"direct": false,
"version": "0.11.1+wasi-snapshot-preview1",
"ecosystem": "crates"
},
{
"name": "wasi",
"direct": false,
"version": "0.14.3+wasi-0.2.4",
"ecosystem": "crates"
},
{
"name": "wasm-bindgen",
"direct": false,
"version": "0.2.100",
"ecosystem": "crates"
},
{
"name": "wasm-bindgen-backend",
"direct": false,
"version": "0.2.100",
"ecosystem": "crates"
},
{
"name": "wasm-bindgen-macro",
"direct": false,
"version": "0.2.100",
"ecosystem": "crates"
},
{
"name": "wasm-bindgen-macro-support",
"direct": false,
"version": "0.2.100",
"ecosystem": "crates"
},
{
"name": "wasm-bindgen-shared",
"direct": false,
"version": "0.2.100",
"ecosystem": "crates"
},
{
"name": "web-sys",
"direct": false,
"version": "0.3.77",
"ecosystem": "crates"
},
{
"name": "which",
"direct": false,
"version": "4.4.2",
"ecosystem": "crates"
},
{
"name": "winapi-util",
"direct": false,
"version": "0.1.10",
"ecosystem": "crates"
},
{
"name": "windows-core",
"direct": false,
"version": "0.61.2",
"ecosystem": "crates"
},
{
"name": "windows-implement",
"direct": false,
"version": "0.60.0",
"ecosystem": "crates"
},
{
"name": "windows-interface",
"direct": false,
"version": "0.59.1",
"ecosystem": "crates"
},
{
"name": "windows-link",
"direct": false,
"version": "0.1.3",
"ecosystem": "crates"
},
{
"name": "windows-result",
"direct": false,
"version": "0.3.4",
"ecosystem": "crates"
},
{
"name": "windows-strings",
"direct": false,
"version": "0.4.2",
"ecosystem": "crates"
},
{
"name": "windows-sys",
"direct": false,
"version": "0.59.0",
"ecosystem": "crates"
},
{
"name": "windows-sys",
"direct": false,
"version": "0.60.2",
"ecosystem": "crates"
},
{
"name": "windows-targets",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows-targets",
"direct": false,
"version": "0.53.3",
"ecosystem": "crates"
},
{
"name": "windows_aarch64_gnullvm",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows_aarch64_gnullvm",
"direct": false,
"version": "0.53.0",
"ecosystem": "crates"
},
{
"name": "windows_aarch64_msvc",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows_aarch64_msvc",
"direct": false,
"version": "0.53.0",
"ecosystem": "crates"
},
{
"name": "windows_i686_gnu",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows_i686_gnu",
"direct": false,
"version": "0.53.0",
"ecosystem": "crates"
},
{
"name": "windows_i686_gnullvm",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows_i686_gnullvm",
"direct": false,
"version": "0.53.0",
"ecosystem": "crates"
},
{
"name": "windows_i686_msvc",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows_i686_msvc",
"direct": false,
"version": "0.53.0",
"ecosystem": "crates"
},
{
"name": "windows_x86_64_gnu",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows_x86_64_gnu",
"direct": false,
"version": "0.53.0",
"ecosystem": "crates"
},
{
"name": "windows_x86_64_gnullvm",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows_x86_64_gnullvm",
"direct": false,
"version": "0.53.0",
"ecosystem": "crates"
},
{
"name": "windows_x86_64_msvc",
"direct": false,
"version": "0.52.6",
"ecosystem": "crates"
},
{
"name": "windows_x86_64_msvc",
"direct": false,
"version": "0.53.0",
"ecosystem": "crates"
},
{
"name": "wit-bindgen",
"direct": false,
"version": "0.45.0",
"ecosystem": "crates"
},
{
"name": "writeable",
"direct": false,
"version": "0.6.1",
"ecosystem": "crates"
},
{
"name": "yoke",
"direct": false,
"version": "0.8.0",
"ecosystem": "crates"
},
{
"name": "yoke-derive",
"direct": false,
"version": "0.8.0",
"ecosystem": "crates"
},
{
"name": "zerocopy",
"direct": false,
"version": "0.8.33",
"ecosystem": "crates"
},
{
"name": "zerocopy-derive",
"direct": false,
"version": "0.8.33",
"ecosystem": "crates"
},
{
"name": "zerofrom",
"direct": false,
"version": "0.1.6",
"ecosystem": "crates"
},
{
"name": "zerofrom-derive",
"direct": false,
"version": "0.1.6",
"ecosystem": "crates"
},
{
"name": "zerotrie",
"direct": false,
"version": "0.2.2",
"ecosystem": "crates"
},
{
"name": "zerovec",
"direct": false,
"version": "0.11.4",
"ecosystem": "crates"
},
{
"name": "zerovec-derive",
"direct": false,
"version": "0.11.1",
"ecosystem": "crates"
}
],
"collected": true,
"truncated": false,
"total_count": 301,
"direct_count": 26,
"indirect_count": 275
}
},
"maintainership": {
"issues": {
"open_prs": 1,
"merged_prs": 274,
"open_issues": 6,
"closed_ratio": 0.962,
"closed_issues": 153,
"closed_unmerged_prs": 16
},
"bus_factor": 1,
"bot_contributors": 2,
"top_contributors": [
{
"type": "User",
"login": "joshrotenberg",
"commits": 244,
"avatar_url": "https://avatars.githubusercontent.com/u/3231?v=4"
},
{
"type": "User",
"login": "Evers-Perez",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/86700631?v=4"
}
],
"contributors_sampled": 2,
"top_contributor_share": 0.996
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yml",
"corpus-testing.yml",
"docker.yml",
"docs.yml",
"mdbook-compatibility.yml",
"release-plz.yml",
"release.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"Cargo.lock"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 3,
"reason": "branch protection is not maximal on development and all release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 9,
"reason": "28 out of 29 merged PRs checked by a CI test -- score normalized to 9",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 1/29 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 3,
"reason": "project has 1 contributing companies or organizations -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 10,
"reason": "update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 9,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "27 commit(s) and 21 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": 0,
"reason": "Project has not signed or included provenance with any releases.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 9,
"reason": "1 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "e67ca47a9cf54e1d1fd88e3e84ab898a771df3e5",
"ran_at": "2026-07-29T08:32:07Z",
"aggregate_score": 4.9,
"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-27T23:45:17Z",
"oldest_open_prs": [
{
"number": 400,
"created_at": "2026-05-22T17:55:34Z",
"last_comment_at": "2026-06-02T23:55:10Z",
"last_comment_author": "codecov-commenter"
}
],
"last_merged_pr_at": "2026-07-27T23:42:44Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 300,
"created_at": "2025-12-11T15:35:35Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 301,
"created_at": "2025-12-11T15:35:50Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 416,
"created_at": "2026-07-06T21:33:37Z",
"last_comment_at": "2026-07-27T22:49:16Z",
"last_comment_author": "joshrotenberg"
},
{
"number": 417,
"created_at": "2026-07-06T21:33:51Z",
"last_comment_at": "2026-07-27T22:49:17Z",
"last_comment_author": "joshrotenberg"
},
{
"number": 418,
"created_at": "2026-07-06T21:34:06Z",
"last_comment_at": "2026-07-27T22:49:18Z",
"last_comment_author": "joshrotenberg"
},
{
"number": 420,
"created_at": "2026-07-06T21:36:29Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/joshrotenberg/mdbook-lint",
"host": "github.com",
"name": "mdbook-lint",
"owner": "joshrotenberg"
},
"metrics": {
"overall": {
"key": "overall",
"band": "good",
"name": "Overall health",
"note": "The weighted overall 65 is calibrated to 75 on the published index scale (record calibration 2026-08-02).",
"notes": [
{
"code": "overall_calibration",
"params": {
"raw": 65,
"calibrated": 75,
"calibration": "2026-08-02"
}
}
],
"value": 75,
"inputs": {
"security": 59,
"vitality": 81,
"community": 48,
"governance": 60,
"calibration": "2026-08-02",
"engineering": 76,
"ai_readiness": 62,
"weighted_overall_raw": 65
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 81,
"weight": 0.21,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"commits_last_year": 277,
"human_commit_share": 0.89,
"days_since_last_push": 1,
"active_weeks_last_year": 16
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 1 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 1
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "16/52 weeks with commits",
"points": 11.1,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 16
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "277 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 277
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "27 commit(s) and 21 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"releases_count": 31,
"latest_release_tag": "v0.15.0",
"releases_from_tags": false,
"days_since_latest_release": 1,
"mean_days_between_releases": 25.3
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "31 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 31
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 1 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 1
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~25.3 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 25.3
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "exceptional",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 7,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 7 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 7
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "weak",
"name": "Community & Adoption",
"value": 48,
"weight": 0.17,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 26,
"inputs": {
"forks": 3,
"stars": 27,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "27 stars",
"points": 23,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 27
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "3 forks",
"points": 2.5,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 3
}
}
],
"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": 64,
"inputs": {
"has_readme": true,
"has_license": true,
"readme_badges": null,
"has_contributing": true,
"has_issue_template": false,
"has_code_of_conduct": false,
"readme_badge_services": [],
"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": "license file present, not a recognized license",
"points": 16.9,
"status": "partial",
"details": [
{
"code": "license_custom",
"params": {}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 61,
"inputs": {
"packages": [
"mdbook-lint",
"mdbook-lint-core",
"mdbook-lint-rulesets"
],
"dependents": null,
"ecosystems": "crates",
"total_downloads": 30894,
"monthly_downloads": 4815
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "4,815 downloads/month across crates",
"points": 49.1,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 4815,
"ecosystems": "crates"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 60,
"weight": 0.23,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 15,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 2,
"top_contributor_share": 0.996
},
"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.1,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "2 contributors",
"points": 2.7,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 2
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Newcomer PR acceptance. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"newcomer_pr_acceptance"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 79,
"inputs": {
"merged_prs": 274,
"open_issues": 6,
"closed_issues": 153,
"prs_merged_7d": null,
"prs_decided_7d": null,
"prs_merged_30d": null,
"prs_decided_30d": null,
"issue_closed_ratio": 0.962,
"closed_unmerged_prs": 16,
"first_time_authors_30d": null,
"first_time_prs_merged_30d": null,
"first_time_prs_decided_30d": null
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "96% of issues closed",
"points": 40.4,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 96
}
}
],
"max_points": 42
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "274/290 decided PRs merged",
"points": 28.3,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 274,
"decided": 290
}
}
],
"max_points": 30
},
{
"key": "newcomer_pr_acceptance",
"name": "Newcomer PR acceptance",
"detail": "no first-time contributor's PR decided in 30d",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_newcomer_prs",
"params": {
"days": 30
}
}
],
"max_points": 13
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 1/29 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 62,
"inputs": {
"followers": 92,
"owner_type": "User",
"is_verified": null,
"owner_login": "joshrotenberg",
"public_repos": 225,
"account_age_days": 6707
},
"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": "92 followers of joshrotenberg",
"points": 14.2,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 92,
"login": "joshrotenberg"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "225 public repos, account ~18 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 225
}
},
{
"code": "account_age_years",
"params": {
"years": 18
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "exceptional",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"mdbook-lint",
"mdbook-lint-core",
"mdbook-lint-rulesets"
],
"ecosystems": "crates",
"any_deprecated": false,
"min_days_since_publish": 1
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "3 package(s) on crates",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 3,
"ecosystems": "crates"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 1 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 1
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "29 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 29
}
}
],
"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": "good",
"name": "Engineering Quality",
"value": 76,
"weight": 0.19,
"metrics": [
{
"key": "engineering_practices",
"band": "good",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 66,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "7 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 7
}
}
],
"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": "28 out of 29 merged PRs checked by a CI test -- score normalized to 9",
"points": 18,
"status": "partial",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"topics": [
"lint",
"linter",
"markdown",
"mdbook",
"mdbook-plugins",
"mdbook-preprocessor"
],
"has_wiki": false,
"homepage": "https://joshrotenberg.com/mdbook-lint/",
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://joshrotenberg.com/mdbook-lint/",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "6 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 6
}
}
],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 59,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "weak",
"name": "Security posture",
"note": null,
"notes": [],
"value": 49,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 18,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 0,
"scorecard_aggregate": 4.9
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection is not maximal on development and all release branches",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "28 out of 29 merged PRs checked by a CI test -- score normalized to 9",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 1/29 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 0.8,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "update tool detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "27 commit(s) and 21 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "1 existing vulnerabilities detected",
"points": 6.8,
"status": "partial",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "dependency_advisories",
"band": "exceptional",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 293 resolved dependencies against OSV; 8 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"indirect_dependencies_free_of_known_advisories",
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 293
}
},
{
"code": "advisories_unassessed",
"params": {
"count": 8
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 1,
"affected_packages": 1,
"assessed_packages": 293,
"unassessed_packages": 8,
"affected_by_severity": "unknown 1",
"direct_affected_packages": 0
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "no direct dependency carries a known advisory",
"points": 35,
"status": "met",
"details": [
{
"code": "no_direct_advisories",
"params": {}
}
],
"max_points": 35
},
{
"key": "indirect_dependencies_free_of_known_advisories",
"name": "Indirect dependencies free of known advisories",
"detail": "transitive set not separable from development and test dependencies in this scope",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_scope_not_separable",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "no advisory carries a publication date",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_no_publication_date",
"params": {}
}
],
"max_points": 40
}
]
},
{
"key": "malicious_dependencies",
"band": "exceptional",
"name": "Malicious dependencies",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"source": "osv",
"meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
"packages": [],
"red_flag": false,
"assessed_packages": 293,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "exceptional",
"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"
],
"commit_weight_rule": {
"min_commits": 50,
"min_commit_share": 0.1
},
"review_only_matches": 0,
"below_threshold_exposures": [],
"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": "moderate",
"name": "AI Readiness",
"value": 62,
"weight": 0.04,
"metrics": [
{
"key": "ai_agent_context",
"band": "weak",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 1,
"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": "89 of 89 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 89,
"sampled": 89
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 64,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"Cargo.lock"
],
"has_dockerfile": true,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0,
"toolchain_manifests": [
"Cargo.toml",
"crates/mdbook-lint-cli/Cargo.toml",
"crates/mdbook-lint-core/Cargo.toml",
"crates/mdbook-lint-rulesets/Cargo.toml"
],
"dependency_bot_commit_share": 0.03
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Cargo.toml, crates/mdbook-lint-cli/Cargo.toml, crates/mdbook-lint-core/Cargo.toml (toolchain convention, no task runner)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "toolchain_convention",
"params": {
"files": "Cargo.toml, crates/mdbook-lint-cli/Cargo.toml, crates/mdbook-lint-core/Cargo.toml"
}
}
],
"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": "Rust (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Rust"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "Dockerfile, lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Dockerfile, lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "3 of the last 100 commits are automated dependency updates",
"points": 8,
"status": "met",
"details": [
{
"code": "dependency_bot_commits",
"params": {
"count": 3,
"sampled": 100
}
}
],
"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": "exceptional",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Rust",
"largest_source_bytes": 84284,
"source_files_sampled": 146,
"oversized_source_files": 1
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Rust (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Rust"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "1/146 source files over 60KB",
"points": 54.6,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 146,
"oversized": 1
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)."
}
],
"classification": {
"top": [
"library",
"application"
],
"labels": [
"cli",
"library"
],
"scores": {
"cli": 8,
"library": 8
},
"primary": "cli",
"evidence": [
{
"tier": "distribution",
"label": "library",
"source": "registry:crates",
"weight": 6
},
{
"tier": "dependencies",
"label": "cli",
"source": "dep:clap",
"weight": 4
},
{
"tier": "tags",
"label": "cli",
"source": "tag:lint",
"weight": 2
},
{
"tier": "tags",
"label": "cli",
"source": "tag:linter",
"weight": 2
},
{
"tier": "tags",
"label": "library",
"source": "tag:library",
"weight": 2
}
],
"artifacts": [],
"confidence": "medium",
"host_extension": false,
"runs_as_process": true,
"consumed_by_code": true
},
"metrics_version": "2.5.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
],
"report_type": "repository",
"generated_at": "2026-07-29T08:32:26.653516Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/j/joshrotenberg/mdbook-lint.svg",
"full_name": "joshrotenberg/mdbook-lint",
"license_state": "custom",
"license_spdx": null
}