). Previously any line beginning with `..` was\nrejected as a title, so the marker line became a paragraph and the\nfollowing block lost its title.\n\nCloses #957\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Recognize block title with a leading period (`..name`) (#958)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-25T15:51:18Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "320ce4bdfac06a8ba4b9a1e1c684c0587ee43276", "body": null, "is_bot": false, "headline": "chore(asciidoc-parser): release v0.27.0 (#941)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-25T04:25:25Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "aa767ff5cde506e86b4361ababa6c0266d9c44ac", "body": "* fix: capture block metadata on list items instead of dropping it\n\n`ListBlock::parse` built each list item with an empty `BlockMetadata`, so a\ntitle, anchor, or attribute list written directly before a list item's marker\nwas silently discarded. Worse, because the empty metadata could not parse past\n[…]\nt for them, restoring the original fast path for\nthe common paragraph case.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Capture block metadata on list items instead of dropping it (#954)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-25T04:22:04Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "c4c7294195664e7d3005c7cc48796c9a2fdc9fcd", "body": "* chore: Pin GitHub Actions to specific commit SHAs\n\nReplace mutable version tags with pinned commit SHAs (each with a\ntrailing version comment) across ci.yml and pr_title.yml, following the\npattern already used in release.yml. Each SHA is the commit its tag or\nbranch currently resolves to. This har\n[…]\n currently resolves to) so all\nthree workflows share a single checkout SHA.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore: Pin GitHub Actions to specific commit SHAs (#955)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-25T04:04:49Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "b34f99e95e10c41ff93d4c26edf3ae455560998c", "body": "Part of the #939 TEMPORARY-marker audit. The `#[allow(...)]` attributes\nguarding test scaffolding are no longer warranted:\n\n- `assert_dom/virtual_dom.rs`: the `VirtualNode` builder helpers are now\n used throughout the DOM assertions, so the blanket `#[allow(dead_code)]`\n on the impl block is remov\n[…]\nunconstructed, so per the audit guidance they (and their\n `Debug` / equality arms) are removed rather than left behind an allow.\n\nCloses #949.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore: Remove consumed 'while building' scaffolding allows (#949) (#952)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-25T03:42:14Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "8944d9105400fdba9e9d7fa29d266ad1ecf38818", "body": "…o_name (#953)\n\n`Span::take_ident` borrowed Rust's identifier definition (leading\nalphabetic/underscore, then alphanumerics/underscores) because\n\"identifier\" is not crisply defined in the AsciiDoc documentation. Its\nuse was already discouraged in favor of more specific helpers.\n\nThere was a single c\n[…]\nng digit) is now parsed and then rejected as unrecognized\nrather than rejected at the name-capture stage, with identical results.\n\nCloses #948.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "refactor: Replace Span::take_ident with spec-grounded take_block_macr…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-25T03:40:42Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "78d9373b0f7d80bbd965d48ec60c5924b6592832", "body": "…947) (#951)\n\nThe `Block` enum's variants have converged in size as the parser\nevolved. The two largest, `Section` (568 bytes) and `Media` (536\nbytes), now differ by only 32 bytes – far under clippy's 200-byte\n`large_enum_variant` threshold – so the lint no longer fires. The\n`#[allow]` (carried forw\n[…]\nasoning already\ndocumented on `BlockParseOutcome`).\n\nVerified with the CI invocation\n`cargo clippy --all-features --all-targets -- -Dwarnings`.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore: Drop stale allow(clippy::large_enum_variant) on Block (close #…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-25T03:40:16Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "19faf3b5696dfb32a0f875f4d95ddb93db7a8706", "body": "Audit the code base for TEMPORARY / \"while building\" markers (excluding\n`ref` and tests quoting `ref` content) and convert the genuine ones to\nTODO comments that link to tracking issues, per #939.\n\n- List items discard block metadata (#946).\n- `Block` enum trips `clippy::large_enum_variant` (#947).\n- `Span::take_ident` uses a provisional identifier definition (#948).\n- Remove \"while building\" scaffolding allows once consumed (#949).\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore: replace TEMPORARY markers with issue-linked TODOs (#950)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-25T03:19:25Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "5fdf0f42b24c7d41e72c1df86811d1789cd3eaba", "body": "Code-coverage review for dead code found no removable dead code: line\ncoverage is 98.79% and the compiler's dead_code lint is clean. The\nuncovered product lines are all intentional guardrails (defensive\nbranches, assertions, Debug impls, and a refactor-blocked region).\n\nThe one actionable cleanup is this stale attribute: the re-export is now\nused via crate::document::DuplicateIdError in the parser, so the\nallow(unused) suppresses nothing.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore: Remove stale allow(unused) on DuplicateIdError re-export (#945)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T23:05:40Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "4bbb8fe9f0018185442bda7a16e44b199f8a8e60", "body": "…haustive (#940)\n\n* feat: Derive Hash on the public AST / output types\n\nSpan, Block, Content, WarningType and the types reachable from them now\nimplement Hash, so blocks and spans can key a HashMap/HashSet and warnings can\nbe bucketed by type. ResolvedAttributes hashes an order-independent summary o\n[…]\nleValue / ModificationContext fields, all of which hold only Hashable\ndata.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "feat: Derive Hash on the public AST/output types; mark Warning non_ex…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T21:39:56Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "a59f603280d80c729d8a0f80afdb3554901d187b", "body": "…pat 5.0.0 -> 5.0.1 (#938)\n\nPatch-level updates to the benchmark harness dev-dependencies. Raising the\ndeclared floors keeps the -Z direct-minimal-versions CI job on the current\npatch releases. Benchmarks compile and minimal-versions resolves cleanly.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore(deps): Bump criterion 0.8.0 -> 0.8.2 and codspeed-criterion-com…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T19:03:52Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "ca8db26179c0fe77d71e8e55b3a358fde32945af", "body": "* chore(asciidoc-parser): release v0.26.0\n\n* docs: Add 0.26.0 breaking changes guide to the changelog\n\nDocument the source-level migration for the four breaking changes in\n0.26.0 (block traversal #930, PathResolver-as-trait #934, rendering API\npolish #929, and the SourceMap reshape #917), mirroring the prose\nguide added for 0.23.0.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore(asciidoc-parser): release v0.26.0 (#916)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T15:52:19Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "50f68b5578c980dbfe90d73256b5b3e3e8b27f97", "body": "…ers (close #896) (#933)\n\n* feat: Let a custom InlineSubstitutionRenderer override only what differs (close #896)\n\nTwo changes unblock a downstream (e.g. Zola) `InlineSubstitutionRenderer`:\n\n- Give every `InlineSubstitutionRenderer` method a default body that\n delegates to the built-in `HtmlSubstit\n[…]\n is not surprised that `render_icon` and a direct `icon_uri`\ncall disagree.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "feat: Let a custom InlineSubstitutionRenderer override only what diff…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T15:42:28Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "104ed44bd5ba50724bb852dbc58f9d423dcb9105", "body": "Warnings were deterministic but assembled by category (header, blocks,\npreprocessor, substitution, post-parse checks, then reference-resolution\nwarnings appended last), so an unresolved `include::` on an early line\ncould sort after a malformed inline macro further down, and unresolved-xref\nwarnings \n[…]\ne parse and after\na reference-resolution sweep folds its warnings in, so `warnings()` now\nyields line-ordered, still-deterministic diagnostics.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Emit document warnings in source order (close #901) (#932)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T15:06:54Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "0202092e25f780df3441880c100fca1f2ed8082b", "body": "…(#936)\n\nPRs #930 (child_blocks API) and #934 (PathResolver trait) landed\nconcurrently without a rebase, leaving the with_path_resolver test\ncalling the removed Document::nested_blocks(). Point it at\nchild_blocks() to match the sibling call sites.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Repair stale nested_blocks() call left by concurrent PR landing …", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T14:36:01Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "e454b6e3c8507d1dc916f572a55b0d13de7b22ad", "body": "…k=self (close #919) (#927)\n\n* fix: Reject a dangerous image/icon target promoted to an href via link=self (close #919)\n\nAn `image:`/`icon:` macro whose target carries a script-capable scheme\n(`javascript:`, `vbscript:`, or a non-image `data:` such as\n`data:text/html,…`) is harmless in the `\u003cimg src\n[…]\nage data URIs and trusted embedded SVGs (the Asciidoctor-parity case) live.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Reject a dangerous image/icon target promoted to an href via lin…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T14:27:49Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "08944ce4a76acacdb4515e1b549df4728080162e", "body": "…r (close #898) (#934)\n\nPath resolution was the one extensibility seam in the crate that could not\nbe swapped: `PathResolver` was a concrete struct exposed as a `pub` by-value\nfield on `Parser`, so an Antora/Zola-style host needing custom path or URL\nrewriting (virtual filesystems, content roots, UR\n[…]\n` field is now `pub(crate) Rc\u003cdyn PathResolver>`,\nconfigured through a new `with_path_resolver(...)` builder rather than direct\nfield mutation.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "refactor!: Make PathResolver a trait with a with_path_resolver builde…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T14:21:36Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "d01724d237725af16b2892d5572cc95e102b7443", "body": "…I (close #894) (#930)\n\n* feat!: replace IsBlock::nested_blocks with a complete child_blocks API (close #894)\n\nThe discoverable block accessor `IsBlock::nested_blocks()` silently omitted\nMarkdown-blockquote children (reachable only via `QuoteBlock::blocks()`) and\nAsciiDoc table-cell content, so tool\n[…]\nck`, and\n the `nth` override) generated by the `opaque_slice_iter!` macro.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "feat!: Replace IsBlock::nested_blocks with a complete child_blocks AP…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T14:18:52Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "6dbdb248bb87626baa8087ac7c6ef5cbc0f52de9", "body": "…#903) (#931)\n\n* fix: Enforce SourceMap append ordering with a debug assertion (close #903)\n\n`SourceMap::resolve` binary-searches `segments` by `output_line`, which\nsilently returns garbage on an unsorted slice. `append` documented that\nentries \"should\" arrive in increasing order but did not enforce\n[…]\nptile-apps[bot]@users.noreply.github.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>\nCo-authored-by: greptile-apps[bot] \u003c165735046+greptile-apps[bot]@users.noreply.github.com>", "is_bot": false, "headline": "fix: Enforce SourceMap append ordering with a debug assertion (close …", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T14:14:12Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "5cb17dc58929cd6e654764f8b50a06e222229607", "body": "…se #899) (#926)\n\n`Catalog::ids()` and `Catalog::entries()` iterated a randomly-seeded\n`HashMap`, so their order varied between process runs. A multi-document\npipeline that derives output from catalog iteration order (e.g. building a\nglobal cross-reference index, or resolving a collision as \"first s\n[…]\nookups. `DebugHashMapFrom` is generalized to render either map type and\nstill sorts its own output, so the `Debug` representation is unchanged.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Make catalog ID iteration deterministic across process runs (clo…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T14:02:54Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "7f1df812544eadf0f48551d0b98abfba3a438e77", "body": "…e #906) (#925)\n\nThe doc comment read only \"Alternative to\" with a TODO placeholder. Describe\nthat `LookaheadReplacer` is an alternative to `regex::Replacer` that can inspect\nthe text following a match and reject it via `SkipAheadAndRetry`, modeling the\nlook-ahead pattern that `regex::Replacer` cannot express.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "docs: Complete the truncated doc comment on `LookaheadReplacer` (clos…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T13:34:38Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "8eef1e68450f576f513f568f1a1a33d8daf724ff", "body": "…K branch (close #908) (#928)\n\nThe invalid-macro-syntax `else` branch in `InlineLinkReplacer` carried a\nFIXME noting that a `link:` prefix should never reach it: the shared\nNON-ANGLE branch of `INLINE_LINK` let `link:` prefix a bare (bracket-less)\nURL, which then matched and was rejected as invalid \n[…]\nsyntax path.\n\n`NormalizedCaps` gains a third branch mapping and `bare` becomes optional\n(the LINK-MACRO branch always has a trailing attrlist).\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "refactor: Give the `link:` prefix its own bracket-required INLINE_LIN…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T13:32:34Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "024721f9252180c4962152effea6365cc966c97d", "body": "Settles several pre-1.0 public-API commitments flagged in the adversarial\nreview, each of which would become a breaking change to fix after the freeze:\n\n- Rename the misspelled trait method\n `InlineSubstitutionRenderer::render_quoted_substitition` to\n `render_quoted_substitution`.\n- Remove the pro\n[…]\n type and\n`LinkRenderParams::type_` field are removed; and `LinkRenderParams::window`\nchanges from `Option\u003c&'static str>` to `Option\u003c&'a str>`.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "refactor!: Polish public rendering API ahead of 1.0 (close #897) (#929)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T13:30:31Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "91abb32cc09f6a331ac1c2898655248cb54037be", "body": "…ion (close #889) (#920)\n\nAdd a prominent \"Security: rendering untrusted input\" section to the\nREADME (which is also the crate-level doc via `include_str!`), stating\nthat the HTML renderer is not a sanitizer, that attribute-reference\nsubstitution and passthroughs emit raw HTML by design, and that\nco\n[…]\noc must run the output\nthrough an HTML sanitizer such as `ammonia`. Clarify that safe mode\ngoverns file/environment reach, not output escaping.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "docs: Document that untrusted AsciiDoc output requires HTML sanitizat…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T05:14:55Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "870609273fe4653c8dd8ecea622099c3543654ff", "body": "…05) (#924)\n\n* perf: Reduce allocations in the inline substitution pipeline (close #905)\n\nResidual allocation-reduction items from the adversarial review; each is\nsmall and mechanical, and the many-small-blocks-of-plain-prose throughput\ncase benefits from all of them.\n\n- `apply_special_characters` n\n[…]\nng both the\n no-op-filter borrow branch and the changed-text owned branch.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Reduce allocations in the inline substitution pipeline (close #9…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T05:14:23Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "e053106f32bb6358554dfd2f3fc584574ff3e393", "body": "…ounds slice (close #902) (#923)\n\n* fix: Fall back to an empty span instead of the whole span on out-of-bounds slice (close #902)\n\n`Span::slice` / `slice_from` / `slice_to` guarded their bounds only with a\n`debug_assert!`. In a release build, when `.get(range)` returned `None`, the\n`map_or(*self, …)\n[…]\nes;\nthe release fallback behavior is already covered by the `empty()` test.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Fall back to an empty span instead of the whole span on out-of-b…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T05:13:38Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "6ad42b74d3ae456eeccab4f1f7a6dc8504208804", "body": "…ciiDoc table cells (close #904) (#922)\n\nFor every AsciiDoc-style (`a`) table cell, `process_content` rebuilt the\nattribute-lock set from scratch, allocating an owned `String` for each of the\n~74 built-in attributes it locked and deep-cloning the whole `HashSet\u003cString>`\nper cell. This was the domina\n[…]\ncall out of the modifiable-attributes loop so the\nper-parser attribute map is made-mut once per cell rather than re-checked on\nevery iteration.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "perf: Avoid per-cell String allocations when locking attributes in As…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T05:07:35Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "24ec6d181229f6d09f8dccdcf646fbd5ef918cad", "body": "…or (close #907) (#921)\n\nThe `// TODO:` in `section_to_node` described how the section title heading is\nadded in the `Block::Section` match arm (using `section.level()` for the heading\nlevel and `section.section_title()` for the text). That behavior is already fully\nimplemented there, so the note tr\n[…]\nfold its one useful detail (the title heading, like the id,\nlands on the heading rather than the wrapper `\u003cdiv>`) into the surrounding\ncomment.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore: Remove stale TODO restating implemented section-heading behavi…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T05:07:00Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "80825d50579108831d9bc1f96f5a6e9e43d86cdd", "body": "…idelity (#917)\n\n* feat: Map preprocessed spans back to origin file, line, column, and fidelity (close #891)\n\nSpans carry coordinates relative to the single preprocessed buffer, and the\nonly way back to an origin was `SourceMap::original_file_and_line`, which is\nline-only and cannot say whether a li\n[…]\nhe included file's identity is\nnot carried forward into the parent's lines.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "feat: Map preprocessed spans back to origin file, line, column, and f…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T04:47:54Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "e64f4ade1fff3da5fba49aebf0aba8c2fb15d6dd", "body": "…k macro (close #888) (#911)\n\n* fix: Escape href/target/icon attributes and reject script URIs in link macro (close #888)\n\nSeveral `href`/`target` and icon attribute values were emitted into the\nrendered HTML without escaping the `\"` delimiter, allowing an author to\nbreak out of the attribute and in\n[…]\nnd `render_icon_or_image` (which drops the\nlive link) share one definition.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Escape href/target/icon attributes and reject script URIs in lin…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T01:59:19Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "0c93961c8288c853f6300d9487cb0139a3afe9b2", "body": "A UTF-8 byte-order mark (`EF BB BF` = U+FEFF) at the start of the input\nwas not stripped. `preprocess` short-circuits and returns the source\nunchanged when there are no directives, so the U+FEFF became the first\ncharacter of the first line. `Header::parse` requires the line to start\nwith `= `, so a \n[…]\n This matches Asciidoctor, which strips a UTF-8 BOM even\nfor UTF-8 input, and is independent of UTF-16 transcoding, which remains\nout of scope.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Strip a leading UTF-8 BOM before parsing (close #900) (#918)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T01:45:04Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "436d8144f64c066572d62d4581da228bf52601ec", "body": "…nput (close #885) (#910)\n\n* fix: Cap block nesting depth to prevent stack overflow on untrusted input (close #885)\n\nBlock parsing descends recursively through `parse_blocks_until` (delimited\nblock bodies, section bodies, table cells, quote/blockquote content) and\nthrough `ListBlock::parse_inside_li\n[…]\ntores parity with\nthe pre-#885 baseline (measured within run-to-run noise).\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Cap block nesting depth to prevent stack overflow on untrusted i…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T01:30:04Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "9c91f6f9c6f3916cb55ae67e3fbfeccfb3bfa644", "body": "…r (close #893) (#909)\n\n* fix: Reset document attribute values between parses on a reused Parser (close #893)\n\n`Parser::parse_deferred` reset the catalog, callouts, substitution\nwarnings, section numbering, pending block title, and counters between\nparses but not `attribute_values`, so document-head\n[…]\nic's prose dash convention in the doc comment added by the\nprevious commit.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Reset document attribute values between parses on a reused Parse…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T01:08:35Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "c8aa0e203b0f9a0374a288eab5fcd69524e2134d", "body": "…ad (close #887) (#912)\n\n* fix: Honor char boundary when skipping constrained-monospace look-ahead (close #887)\n\nThe constrained-monospace quote regex's leading boundary group\n`[^\\w&;:\"'`}]` matches any non-word Unicode scalar, including multi-byte\ncharacters. When a failed look-ahead skipped the le\n[…]\nage gap left by\nthe multi-byte fix. The escaped text is preserved verbatim.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Honor char boundary when skipping constrained-monospace look-ahe…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T00:40:36Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "50f578e127fe1a0c76989d01cbf6a21aa8b9a28c", "body": "Apply the documented comment/doc style conventions to hand-written\ncomments and documentation text (excluding the vendored `ref/` tree and\nthe tests that quote it):\n\n- Convert prose em dashes to spaced en dashes (366 lines). The one\n literal em-dash character reference in `virtual_dom.rs` is preser\n[…]\nn test it marks.\n- File tracking issues for an incomplete doc comment and two unlinked\n TODO/FIXME comments, and link them (#906, #907, #908).\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "doc: Normalize comment and doc prose style across the codebase (#915)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T00:37:00Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "a43b990ea8278c9b81394ffd2bff232a57b17a60", "body": "…#886) (#914)\n\n* fix: Avoid O(n²) parse time on many repeated block delimiters (close #886)\n\n`QuoteBlock::parse` runs before `CompoundDelimitedBlock` in block dispatch,\nso it is tried for every delimiter line. Its quoted-paragraph path called\n`read_paragraph` (a scan to the next blank line) before t\n[…]\nlines between\nthem) — the shape that previously triggered O(n²) parse time.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Avoid O(n²) parse time on many repeated block delimiters (close …", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T00:35:44Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "b5252cb2a4b00dd2dd93049da95c2c90d2178eb9", "body": "…ction (close #890) (#913)\n\nThe `Safe` and `Server` docstrings described protections the parser does\nnot actually enforce:\n\n- `Safe` claimed it prevents access to files outside the source file's\n parent directory. This crate performs no filesystem I/O and does not\n port Ruby Asciidoctor's `PathRes\n[…]\nent handler's responsibility —\nand that only `Secure`, not `Server`, disables include/asset embedding.\n\nDocumentation only; no behavior change.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "docs: Correct SafeMode Safe/Server docstrings to match enforced prote…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-24T00:28:44Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "006b8752176d0637c7f3c2535ecbb02f5ba47798", "body": null, "is_bot": false, "headline": "chore(asciidoc-parser): release v0.25.0 (#879)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T15:21:24Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "cfae1bd47ba42ecab7e0585b59f9f80fa7a40c81", "body": null, "is_bot": false, "headline": "chore: Update README to reflect fully feature-complete status (#884)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T15:15:18Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "b2106856ea6c1c62dcd52c1021720ca2d7b5d294", "body": "…(close #871) (#883)\n\n* test: Verify link attrlist enclosure rule for invalid attribute names (close #871)\n\nPromote the \"enclosure only required when the text preceding the equals\nsign matches a valid attribute name\" sentence in the link/URL macro\nattribute-parsing spec from a non-normative note to \n[…]\nor future spec-coverage work and silence the\nunused-macro/-import warnings.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Verify link attrlist enclosure rule for invalid attribute names …", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T15:04:32Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "48407cc93dcdb2524698690360334ec80e85f99e", "body": "… content (close #877) (#881)\n\n`reindent_included_lines` previously returned included content unchanged\nwhenever the `indent` attribute was absent, so `tabsize`-driven tab\nexpansion only fired when `indent` was also supplied.\n\nPer the spec, when `tabsize` is set, tabs are replaced with spaces\nregard\n[…]\nxpansion now runs\nwhenever `tabsize` is positive; indentation normalization is applied\nindependently when `indent` is present and non-negative.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Expand tabs from `tabsize` independently of `indent` on included…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:53:49Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "1c10c0badc6182a1de62af87f02a150e2f994d42", "body": "…ing blank lines (close #876) (#882)\n\nPromote the `to_do_verifies!` block in `document_test.rs` to two real\n`verifies!` tests, backed by an `InlineFileHandler` fixture reproducing\nAsciidoctor's canonical `include-with-leading-blank-line.adoc` (two blank\nlines before the level-0 title).\n\n- A whole-fi\n[…]\ne and sets `:toc:`.\n- `lines=6` selects by original line number, skipping the leading blank\n lines and the title so only the section survives.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "test: Verify document-title & lines= selection for includes with lead…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:53:02Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "de9a4cff700cb105ba39c66753cc902e78bfc5a7", "body": "…lose #801) (#880)\n\n`WarningType` became part of the public API in #799, so its variant names\nand `Display` strings now need to read as a deliberate, consistent set. This\nis the one-time review the long-standing TODO above `InvalidMacroName` asked\nfor.\n\nVariant renames (breaking for anyone matching \n[…]\ner\"). Wording is otherwise unchanged. This changes user-visible\nwarning text.\n\nThe `TODO (#801)` marker is removed now that the review is done.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "refactor(warnings)!: Review WarningType variant names and messages (c…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:44:50Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "0c6a48c7687d434f46b001a991b9aaae7ca4f778", "body": "…878)\n\nConvert the now-testable table structural-container row to verifies! and\nreclassify the permanently-unverifiable / out-of-scope blocks as\nnon_normative! with justifications:\n\n- delimited.rs: the four table delimiters (`|===`, `,===`, `:===`, `!===`)\n now assert the `table` context and conten\n[…]\ne two genuinely-deferred blocks now cite tracking issues #876 (include\ndoctitle recognition / lines= selection) and #877 (block-level tabsize).\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "test: Resolve remaining to_do_verifies! blocks from the #628 sweep (#…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:39:38Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "2f37e9dd217d6c7595c77300828d290df3b15aaa", "body": "…) (#874)\n\n* test: Cover description-list delimiter and anchor rules (close #864)\n\nThe opening `non_normative!` block in `lists/description.rs` reproduced\nseveral normative parsing rules for description lists but none were\nexercised by a test. Split the block so the normative prose is now backed\nby \n[…]\ntrast to\na leading `[[id]]` anchor which becomes part of the rendered term.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": " chore: Cover description-list delimiter and anchor rules (close #864…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:37:26Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "3e721feddf89a868c943c97bf3abb78d0b32387a", "body": "…horthand ID/role order, AsciiDoc-cell directive) (#873)\n\n* test: Cover `title`-attribute fallback for the document title\n\nSplit the `[#title-attr]` `non_normative!` block so the normative\nfallback rule is verified: with no level 0 section title and no\n`doctitle` attribute, a `title` attribute entry\n[…]\name\ndirective on the following line acts as a normal multiline conditional.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore: Close mislabeled-normative coverage gaps (doctitle fallback, s…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:27:21Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "18685312ef868d1f9906882096a40a25a8224b63", "body": "…se #865) (#875)\n\nSeveral inline-macro spec pages wrapped a normative parsing rule in\n`non_normative!` without covering tests. Add `verifies!` coverage for\neach rule the parser already implements correctly, and a justified\n`to_do_verifies!` marker for the one it does not:\n\n- Inline image alt-text: a\n[…]\next before `=` is a valid attribute name. The parser does not yet\n honor this; the marker documents current behavior and is tracked by\n #871.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "test: Cover inline-macro spec rules hidden behind non_normative! (clo…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:26:46Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "9aad9fafcabf48bfd30a115b4693f86279bde551", "body": "…combinators (close #866) (#868)\n\n* test: Cover mixed ifdef/ifndef combinator behavior (close #866)\n\nThe `non_normative!` block in `ifdef_ifndef.rs` stated the normative rule\nthat the `,` (or) and `+` (and) combinators cannot be combined in a single\nconditional-directive expression, but no test asse\n[…]\naffected. Extend `combinators_cannot_be_mixed` to cover the `+`-first case.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Match Asciidoctor's first-delimiter rule for mixed ifdef/ifndef …", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:14:25Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "5051db0ceb815d7961afb2c5fc2d53131d6ee2df", "body": "Port Asciidoctor's `doc.register :links, target` so the parser records\nevery link target it encounters, exposed as `Catalog::links()`. Like the\nimage registry, population is gated on the `catalog_assets` option and\nrecorded in substitution-pass order.\n\nAll four Asciidoctor registration sites are covered: bare-URL autolink,\n`link:` macro, `mailto:`/link macro, and email autolink (the last of\nwhich the original TO DO markers had missed).\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "feat: Populate the document catalog's link registry (close #335) (#872)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:10:34Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "e06f0caf0984685dcb64fa452c10e6ca152a60d2", "body": "Audit of commented-out code turned up two genuinely dead blocks in the\ncrate's own source (excluding quoted Asciidoctor / AsciiDoc reference\nmaterial):\n\n- `passthroughs.rs`: an abandoned trailing-backslash truncation approach,\n superseded by the retry logic that follows it.\n- `sdd/src/main.rs`: a developer debugging shortcut that scoped file\n processing to a single file.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "chore: Remove commented-out dead code (close #705) (#870)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T14:09:52Z", "body_truncated": false, "is_coding_agent": true }, { "oid": "dbacb2413f412cdbee15fd2ebd8ff150b1c77b34", "body": null, "is_bot": false, "headline": "chore(asciidoc-parser): release v0.24.0 (#863)", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T04:33:53Z", "body_truncated": false, "is_coding_agent": false }, { "oid": "99cf75ffb9858f73cb164da754ce25058e314f13", "body": "…tle (#862)\n\nAdd a regression test asserting that a block attribute line above the\ndocument title whose value carries a `{counter:…}` reference does not fire\nthe counter at header time when the run is ultimately rejected (here by an\nembedded `[[anchor]]`).\n\n`document_title_follows_block_metadata` sc\n[…]\nparser and the counter advances exactly once. This\nlocks in that behavior, salvaging the one piece of unique coverage from the\nsuperseded #833.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "test: Cover counter deferral for a rejected metadata run above the ti…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T04:27:28Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "0944b66c0ba58ae3c2a2dc942f070698241756d1", "body": "…ub (#861)\n\nIssue #308 asked whether a block title can span multiple lines via a\ntrailing `+`. The answer is no: a title is a single line, and a trailing\n` +` is retained literally rather than joined to the following line\n(confirmed against the parser). Replace the stale `TO DO` comment linking\nto #\n[…]\n `to_do_verifies!` stub convention.\n\nThe `|Titles |{y}` spec-coverage marker stays; that gap is tracked by the\n`to_do_verifies!` sweep in #628.\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "test: Remove resolved #308 reference from post_replacements titles st…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T04:07:15Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "adf9ff733355bea5b2dba6b52c30deb736ecbc0d", "body": "…9) (#852)\n\n* fix: Fuse legacy `+`-continued multi-line attribute values (close #729)\n\nAn attribute entry value can be continued across lines with a trailing\n` +` (legacy) as well as ` \\` (modern). Previously only the backslash\ncontinuation was fused; a legacy `+`-continued value was not joined — th\n[…]\nn the document body).\n\nAdds span-, fold-, and parse-level regression tests.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Fuse legacy `+`-continued multi-line attribute values (close #72…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T04:06:45Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "3f2e0d78c748fff27314a181285a2863f43d4b05", "body": "…732) (#850)\n\n* fix: Formal `role=` replaces roles set via shorthand `.role` (close #732)\n\nWhen merging multiple block attribute lines, roles now follow\nAsciidoctor's running model: a formal `role=` entry replaces every role\naccumulated so far, while shorthand `.role` entries append. Previously\nall \n[…]\nat\n the formal value replaces the running roles and the shorthand appends.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "fix: Formal `role=` replaces roles set via shorthand `.role` (close #…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T03:59:34Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "cab8554693ddb8d05d68eb5dd37bdf05384d37ff", "body": "…lose #745) (#848)\n\n* feat: Drop YAML/TOML front matter when `skip-front-matter` is set (close #745)\n\nA `---`-fenced block at the very top of the document is now removed – and\nits content captured in the `front-matter` document attribute – when the\n`skip-front-matter` attribute is set, mirroring Asc\n[…]\n, `+++` TOML is not, and the content is\nstored verbatim rather than parsed.\n\nCo-Authored-By: Claude Opus 4.8 \u003cnoreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com>", "is_bot": false, "headline": "feat: Drop YAML-style front matter when `skip-front-matter` is set (c…", "author_name": "Eric Scouten", "author_login": "scouten", "committed_at": "2026-07-23T03:54:47Z", "body_truncated": true, "is_coding_agent": true } ], "releases_count": 55, "commits_last_year": 546, "latest_release_at": "2026-08-01T16:14:24Z", "latest_release_tag": "v0.29.4", "releases_from_tags": false, "days_since_last_push": 0, "active_weeks_last_year": 37, "days_since_latest_release": 0, "mean_days_between_releases": 0.7 }, "community": { "has_readme": true, "has_license": true, "has_description": true, "has_contributing": false, "health_percentage": 37, "has_issue_template": false, "has_code_of_conduct": false, "has_pull_request_template": false }, "ecosystem": { "packages": [ { "name": "sdd", "exists": true, "license": "Apache-2.0", "keywords": [ "concurrent", "garbage", "memory", "epoch", "lock-free", "data-structures", "concurrency", "memory-management" ], "ecosystem": "crates", "matches_repo": false, "registry_url": "https://crates.io/crates/sdd", "is_deprecated": false, "latest_version": "4.8.8", "repository_url": "https://codeberg.org/wvwwvwwv/scalable-delayed-dealloc", "versions_count": 72, "total_downloads": 77608068, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": 5899173, "first_published_at": "2024-04-14T18:03:40.616625Z", "latest_published_at": "2026-07-02T14:12:15.625601Z", "latest_version_yanked": false, "days_since_latest_publish": 30 }, { "name": "asciidoc-parser", "exists": true, "license": "MIT OR Apache-2.0", "keywords": [ "parser", "asciidoc", "parser-implementations" ], "ecosystem": "crates", "matches_repo": true, "registry_url": "https://crates.io/crates/asciidoc-parser", "is_deprecated": false, "latest_version": "0.29.4", "repository_url": "https://github.com/asciidoc-rs/asciidoc-parser", "versions_count": 55, "total_downloads": 13542, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": 2012, "first_published_at": "2024-10-26T22:27:57.063155Z", "latest_published_at": "2026-08-01T16:14:20.394752Z", "latest_version_yanked": false, "days_since_latest_publish": 0 } ] }, "popularity": { "forks": 4, "stars": 34, "watchers": 2, "fork_history": { "days": [ { "date": "2026-01-23", "count": 1 }, { "date": "2026-02-17", "count": 1 }, { "date": "2026-04-01", "count": 1 }, { "date": "2026-07-18", "count": 1 } ], "complete": true, "collected": 4, "total_forks": 4 }, "star_history": null, "open_issues_and_prs": 5 }, "ai_readiness": { "has_nix": false, "example_dirs": [ "examples" ], "has_llms_txt": false, "has_dockerfile": false, "has_mcp_signal": false, "bootstrap_files": [], "api_schema_files": [], "has_devcontainer": true, "typecheck_configs": [], "toolchain_manifests": [ "Cargo.toml", "parser/Cargo.toml", "sdd/Cargo.toml" ], "largest_source_bytes": 434972, "source_files_sampled": 419, "oversized_source_files": 45, "agent_instruction_files": [], "agent_instruction_max_bytes": null }, "dependencies": { "manifests": [ "Cargo.toml", "parser/Cargo.toml", "sdd/Cargo.toml" ], "advisories": { "error": "No resolved dependencies carried a version and a supported ecosystem", "scope": "repository_graph", "source": null, "findings": [], "collected": false, "malicious": [], "truncated": false, "by_severity": {}, "advisory_count": 0, "affected_count": 0, "assessed_count": 0, "malicious_count": 0, "assessed_package": null, "unassessed_count": 10, "direct_affected_count": 0 }, "ecosystems": [ "crates" ], "dependencies": [ { "name": "bytecount", "manifest": "parser/Cargo.toml", "ecosystem": "crates", "version_constraint": "0.6.7" }, { "name": "memchr", "manifest": "parser/Cargo.toml", "ecosystem": "crates", "version_constraint": "2.6.4" }, { "name": "percent-encoding", "manifest": "parser/Cargo.toml", "ecosystem": "crates", "version_constraint": "2.3.2" }, { "name": "regex", "manifest": "parser/Cargo.toml", "ecosystem": "crates", "version_constraint": "1.11.1" }, { "name": "self_cell", "manifest": "parser/Cargo.toml", "ecosystem": "crates", "version_constraint": "1.2.0" }, { "name": "thiserror", "manifest": "parser/Cargo.toml", "ecosystem": "crates", "version_constraint": "2.0.1" }, { "name": "walkdir", "manifest": "sdd/Cargo.toml", "ecosystem": "crates", "version_constraint": "2.5" } ], "all_dependencies": { "error": null, "source": "github-sbom", "packages": [ { "name": "bytecount", "direct": true, "version": null, "ecosystem": "crates" }, { "name": "memchr", "direct": true, "version": null, "ecosystem": "crates" }, { "name": "percent-encoding", "direct": true, "version": null, "ecosystem": "crates" }, { "name": "regex", "direct": true, "version": null, "ecosystem": "crates" }, { "name": "self_cell", "direct": true, "version": null, "ecosystem": "crates" }, { "name": "thiserror", "direct": true, "version": null, "ecosystem": "crates" }, { "name": "walkdir", "direct": true, "version": null, "ecosystem": "crates" }, { "name": "codspeed-criterion-compat", "direct": false, "version": null, "ecosystem": "crates" }, { "name": "criterion", "direct": false, "version": null, "ecosystem": "crates" }, { "name": "pretty_assertions_sorted", "direct": false, "version": null, "ecosystem": "crates" } ], "collected": true, "truncated": false, "total_count": 10, "direct_count": 7, "indirect_count": 3 } }, "maintainership": { "issues": { "open_prs": 2, "merged_prs": 772, "open_issues": 3, "closed_ratio": 0.987, "closed_issues": 223, "closed_unmerged_prs": 40 }, "bus_factor": 2, "bot_contributors": 1, "top_contributors": [ { "type": "User", "login": "scouten", "commits": 759, "avatar_url": "https://avatars.githubusercontent.com/u/158391?v=4" }, { "type": "User", "login": "mojavelinux", "commits": 723, "avatar_url": "https://avatars.githubusercontent.com/u/79351?v=4" }, { "type": "User", "login": "graphitefriction", "commits": 37, "avatar_url": "https://avatars.githubusercontent.com/u/1124042?v=4" }, { "type": "User", "login": "ggrossetie", "commits": 3, "avatar_url": "https://avatars.githubusercontent.com/u/333276?v=4" }, { "type": "User", "login": "larryv", "commits": 2, "avatar_url": "https://avatars.githubusercontent.com/u/281175?v=4" }, { "type": "User", "login": "mmattel", "commits": 2, "avatar_url": "https://avatars.githubusercontent.com/u/3321281?v=4" }, { "type": "User", "login": "ahus1", "commits": 1, "avatar_url": "https://avatars.githubusercontent.com/u/3957921?v=4" }, { "type": "User", "login": "btat", "commits": 1, "avatar_url": "https://avatars.githubusercontent.com/u/1832069?v=4" }, { "type": "User", "login": "Vampire", "commits": 1, "avatar_url": "https://avatars.githubusercontent.com/u/325196?v=4" }, { "type": "User", "login": "danyill", "commits": 1, "avatar_url": "https://avatars.githubusercontent.com/u/674783?v=4" } ], "contributors_sampled": 22, "top_contributor_share": 0.492 }, "quality_signals": { "has_ci": true, "has_tests": true, "ci_workflows": [ "ci.yml", "pr_title.yml", "release.yml" ], "has_docs_dir": false, "linter_configs": [], "has_editorconfig": false, "has_linter_config": false, "has_precommit_config": false }, "security_signals": { "lockfiles": [], "scorecard": { "checks": [ { "name": "Binary-Artifacts", "score": 10, "reason": "no binaries found in the repo", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts" }, { "name": "Branch-Protection", "score": 3, "reason": "branch protection is not maximal on development and all release branches", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection" }, { "name": "CI-Tests", "score": 10, "reason": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests" }, { "name": "CII-Best-Practices", "score": 0, "reason": "no effort to earn an OpenSSF best practices badge detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices" }, { "name": "Code-Review", "score": 0, "reason": "Found 1/30 approved changesets -- score normalized to 0", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review" }, { "name": "Contributors", "score": 10, "reason": "project has 14 contributing companies or organizations", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors" }, { "name": "Dangerous-Workflow", "score": 10, "reason": "no dangerous workflow patterns detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow" }, { "name": "Dependency-Update-Tool", "score": 10, "reason": "update tool detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool" }, { "name": "Fuzzing", "score": 0, "reason": "project is not fuzzed", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing" }, { "name": "License", "score": 10, "reason": "license file detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license" }, { "name": "Maintained", "score": 10, "reason": "30 commit(s) and 30 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": 10, "reason": "all dependencies are pinned", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies" }, { "name": "SAST", "score": 0, "reason": "SAST tool is not run on all commits -- score normalized to 0", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast" }, { "name": "Security-Policy", "score": 0, "reason": "security policy file not detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy" }, { "name": "Signed-Releases", "score": null, "reason": "no releases found", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases" }, { "name": "Token-Permissions", "score": 0, "reason": "detected GitHub workflow tokens with excessive permissions", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions" }, { "name": "Vulnerabilities", "score": 10, "reason": "0 existing vulnerabilities detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities" } ], "commit": "85320d8042ad10832b6e6cdc5cc7f7ef740c558f", "ran_at": "2026-08-01T18:21:44Z", "aggregate_score": 6.1, "scorecard_version": "v5.5.0" }, "has_codeql_workflow": false, "has_security_policy": false, "has_dependabot_config": true }, "contribution_flow": { "collected": true, "ci_last_run_at": "2026-08-01T17:56:39Z", "oldest_open_prs": [ { "number": 1039, "created_at": "2026-08-01T17:54:25Z", "last_comment_at": "2026-08-01T17:57:42Z", "last_comment_author": "codspeed-hq" }, { "number": 1040, "created_at": "2026-08-01T18:13:36Z", "last_comment_at": "2026-08-01T18:16:29Z", "last_comment_author": "codspeed-hq" } ], "last_merged_pr_at": "2026-08-01T17:53:45Z", "ci_last_conclusion": "SUCCESS", "oldest_open_issues": [ { "number": 943, "created_at": "2026-07-24T22:37:22Z", "last_comment_at": null, "last_comment_author": null }, { "number": 944, "created_at": "2026-07-24T22:37:43Z", "last_comment_at": null, "last_comment_author": null }, { "number": 1036, "created_at": "2026-08-01T17:29:43Z", "last_comment_at": null, "last_comment_author": null } ] } }, "config": { "disabled_metrics": [], "disabled_categories": [], "disabled_components": {} }, "source": { "url": "https://github.com/asciidoc-rs/asciidoc-parser", "host": "github.com", "name": "asciidoc-parser", "owner": "asciidoc-rs" }, "metrics": { "overall": { "key": "overall", "band": "good", "name": "Overall health", "note": "The weighted overall 66 is calibrated to 77 on the published index scale (record calibration 2026-08-02).", "notes": [ { "code": "overall_calibration", "params": { "raw": 66, "calibrated": 77, "calibration": "2026-08-02" } } ], "value": 77, "inputs": { "security": 61, "vitality": 94, "community": 43, "governance": 66, "calibration": "2026-08-02", "engineering": 61, "ai_readiness": 64, "weighted_overall_raw": 66 }, "components": [] }, "categories": [ { "key": "vitality", "band": "exceptional", "name": "Vitality", "value": 94, "weight": 0.21, "metrics": [ { "key": "development_activity", "band": "excellent", "name": "Development activity", "note": null, "notes": [], "value": 90, "inputs": { "commits_last_year": 546, "human_commit_share": 1, "days_since_last_push": 0, "active_weeks_last_year": 37 }, "components": [ { "key": "push_recency", "name": "Push recency", "detail": "last push 0 days ago", "points": 36, "status": "met", "details": [ { "code": "push_recency", "params": { "days": 0 } } ], "max_points": 36 }, { "key": "commit_cadence", "name": "Commit cadence", "detail": "37/52 weeks with commits", "points": 25.6, "status": "partial", "details": [ { "code": "commit_cadence_weeks", "params": { "weeks": 37 } } ], "max_points": 36 }, { "key": "commit_volume", "name": "Commit volume", "detail": "546 commits in the last year", "points": 18, "status": "met", "details": [ { "code": "commits_last_year", "params": { "count": 546 } } ], "max_points": 18 }, { "key": "openssf_scorecard_maintained", "name": "OpenSSF Scorecard: Maintained", "detail": "30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10", "points": 10, "status": "met", "details": [], "max_points": 10 } ] }, { "key": "release_discipline", "band": "exceptional", "name": "Release discipline", "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "openssf_scorecard_signed_releases" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 100, "inputs": { "releases_count": 55, "latest_release_tag": "v0.29.4", "releases_from_tags": false, "days_since_latest_release": 0, "mean_days_between_releases": 0.7 }, "components": [ { "key": "ships_releases", "name": "Ships releases", "detail": "55 releases published", "points": 27, "status": "met", "details": [ { "code": "releases_published", "params": { "count": 55 } } ], "max_points": 27 }, { "key": "release_recency", "name": "Release recency", "detail": "latest release 0 days ago", "points": 36, "status": "met", "details": [ { "code": "release_recency", "params": { "days": 0 } } ], "max_points": 36 }, { "key": "release_cadence", "name": "Release cadence", "detail": "a release every ~0.7 days", "points": 27, "status": "met", "details": [ { "code": "release_cadence", "params": { "gap": 0.7 } } ], "max_points": 27 }, { "key": "openssf_scorecard_signed_releases", "name": "OpenSSF Scorecard: Signed-Releases", "detail": "no releases found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 10 } ] }, { "key": "abandonment", "band": "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": 3, "days_since_last_human_commit_is_floor": false }, "components": [ { "key": "project_is_still_maintained", "name": "Project is still maintained", "detail": "last human commit 3 days ago", "points": 100, "status": "met", "details": [ { "code": "abandonment_maintained", "params": { "days": 3 } } ], "max_points": 100 } ] } ], "description": "Is the project alive — is code being written and are releases shipping?" }, { "key": "community", "band": "weak", "name": "Community & Adoption", "value": 43, "weight": 0.17, "metrics": [ { "key": "popularity", "band": "at_risk", "name": "Popularity & adoption", "note": null, "notes": [], "value": 29, "inputs": { "forks": 4, "stars": 34, "watchers": 2, "growth_state": "unverified", "growth_factor_pct": 100, "growth_unverified_reason": "no_history" }, "components": [ { "key": "stars", "name": "Stars", "detail": "34 stars", "points": 24.6, "status": "partial", "details": [ { "code": "stars", "params": { "count": 34 } } ], "max_points": 60 }, { "key": "forks", "name": "Forks", "detail": "4 forks", "points": 4, "status": "partial", "details": [ { "code": "forks", "params": { "count": 4 } } ], "max_points": 25 }, { "key": "watchers", "name": "Watchers", "detail": "2 watchers", "points": 0, "status": "missed", "details": [ { "code": "watchers", "params": { "count": 2 } } ], "max_points": 15 } ] }, { "key": "community_health", "band": "moderate", "name": "Community health", "note": null, "notes": [], "value": 50, "inputs": { "has_readme": true, "has_license": true, "readme_badges": null, "has_contributing": false, "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": "recognized license (Apache-2.0)", "points": 22.5, "status": "met", "details": [ { "code": "license_standard", "params": {} }, { "code": "license_spdx", "params": { "spdx": "Apache-2.0" } } ], "max_points": 22.5 }, { "key": "contributing_guide", "name": "CONTRIBUTING guide", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 18 }, { "key": "code_of_conduct", "name": "Code of conduct", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 13.5 }, { "key": "issue_template", "name": "Issue template", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 7.2 }, { "key": "pr_template", "name": "PR template", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 6.3 } ] }, { "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": 55, "inputs": { "packages": [ "asciidoc-parser" ], "dependents": null, "ecosystems": "crates", "total_downloads": 13542, "monthly_downloads": 2012 }, "components": [ { "key": "monthly_downloads", "name": "Monthly downloads", "detail": "2,012 downloads/month across crates", "points": 44.1, "status": "partial", "details": [ { "code": "downloads_monthly", "params": { "count": 2012, "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": "good", "name": "Sustainability & Governance", "value": 66, "weight": 0.23, "metrics": [ { "key": "maintainer_resilience", "band": "moderate", "name": "Maintainer resilience (bus factor)", "note": null, "notes": [], "value": 60, "inputs": { "bus_factor": 2, "contributors_sampled": 22, "top_contributor_share": 0.492 }, "components": [ { "key": "bus_factor", "name": "Bus factor", "detail": "2 contributor(s) cover half of all commits", "points": 25.2, "status": "partial", "details": [ { "code": "bus_factor", "params": { "count": 2 } } ], "max_points": 54 }, { "key": "commit_distribution", "name": "Commit distribution", "detail": "top contributor authored 49% of commits", "points": 11.4, "status": "partial", "details": [ { "code": "top_contributor_share", "params": { "share": 49 } } ], "max_points": 22.5 }, { "key": "contributor_breadth", "name": "Contributor breadth", "detail": "22 contributors", "points": 13.5, "status": "met", "details": [ { "code": "contributors_sampled", "params": { "count": 22 } } ], "max_points": 13.5 }, { "key": "openssf_scorecard_contributors", "name": "OpenSSF Scorecard: Contributors", "detail": "project has 14 contributing companies or organizations", "points": 10, "status": "met", "details": [], "max_points": 10 } ] }, { "key": "responsiveness", "band": "excellent", "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": 80, "inputs": { "merged_prs": 772, "open_issues": 3, "closed_issues": 223, "prs_merged_7d": null, "prs_decided_7d": null, "prs_merged_30d": null, "prs_decided_30d": null, "issue_closed_ratio": 0.987, "closed_unmerged_prs": 40, "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": "99% of issues closed", "points": 41.5, "status": "partial", "details": [ { "code": "issues_closed_share", "params": { "share": 99 } } ], "max_points": 42 }, { "key": "pr_acceptance", "name": "PR acceptance", "detail": "772/812 decided PRs merged", "points": 28.5, "status": "partial", "details": [ { "code": "decided_prs_merged", "params": { "merged": 772, "decided": 812 } } ], "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/30 approved changesets -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 15 } ] }, { "key": "stewardship", "band": "at_risk", "name": "Ownership & stewardship", "note": null, "notes": [], "value": 34, "inputs": { "followers": 0, "owner_type": "Organization", "is_verified": null, "owner_login": "asciidoc-rs", "public_repos": 2, "account_age_days": 175 }, "components": [ { "key": "ownership_backing", "name": "Ownership backing", "detail": "organization-owned", "points": 30, "status": "met", "details": [ { "code": "owner_organization", "params": {} } ], "max_points": 30 }, { "key": "verified_domain", "name": "Verified domain", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 20 }, { "key": "owner_reach", "name": "Owner reach", "detail": "0 followers of asciidoc-rs", "points": 0, "status": "missed", "details": [ { "code": "owner_followers", "params": { "count": 0, "login": "asciidoc-rs" } } ], "max_points": 25 }, { "key": "track_record", "name": "Track record", "detail": "2 public repos, account ~0 yr old", "points": 4.4, "status": "partial", "details": [ { "code": "public_repos", "params": { "count": 2 } }, { "code": "account_age_years", "params": { "years": 0 } } ], "max_points": 25 } ] }, { "key": "package_maintenance", "band": "exceptional", "name": "Package maintenance", "note": null, "notes": [], "value": 100, "inputs": { "packages": [ "asciidoc-parser" ], "ecosystems": "crates", "any_deprecated": false, "min_days_since_publish": 0 }, "components": [ { "key": "published_resolvable", "name": "Published & resolvable", "detail": "1 package(s) on crates", "points": 25, "status": "met", "details": [ { "code": "packages_published", "params": { "count": 1, "ecosystems": "crates" } } ], "max_points": 25 }, { "key": "publish_recency", "name": "Publish recency", "detail": "latest publish 0 days ago", "points": 35, "status": "met", "details": [ { "code": "publish_recency", "params": { "days": 0 } } ], "max_points": 35 }, { "key": "version_history", "name": "Version history", "detail": "55 published versions", "points": 20, "status": "met", "details": [ { "code": "published_versions", "params": { "count": 55 } } ], "max_points": 20 }, { "key": "not_deprecated", "name": "Not deprecated", "detail": "active, not deprecated or yanked", "points": 20, "status": "met", "details": [ { "code": "package_not_deprecated", "params": {} } ], "max_points": 20 } ] } ], "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?" }, { "key": "engineering", "band": "moderate", "name": "Engineering Quality", "value": 61, "weight": 0.19, "metrics": [ { "key": "engineering_practices", "band": "good", "name": "Engineering practices", "note": null, "notes": [], "value": 68, "inputs": { "has_ci": true, "has_tests": true, "has_editorconfig": false, "has_linter_config": false, "has_precommit_config": false }, "components": [ { "key": "ci_workflows", "name": "CI workflows", "detail": "3 workflow(s)", "points": 24, "status": "met", "details": [ { "code": "ci_workflows", "params": { "count": 3 } } ], "max_points": 24 }, { "key": "tests_present", "name": "Tests present", "detail": null, "points": 24, "status": "met", "details": [], "max_points": 24 }, { "key": "linter_config", "name": "Linter config", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 16 }, { "key": "pre_commit_hooks", "name": "Pre-commit hooks", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 9.6 }, { "key": "editorconfig", "name": ".editorconfig", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 6.4 }, { "key": "openssf_scorecard_ci_tests", "name": "OpenSSF Scorecard: CI-Tests", "detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10", "points": 20, "status": "met", "details": [], "max_points": 20 } ] }, { "key": "documentation", "band": "moderate", "name": "Documentation", "note": null, "notes": [], "value": 50, "inputs": { "topics": [ "asciidoc", "markup", "parser" ], "has_wiki": false, "homepage": null, "has_readme": true, "has_docs_dir": false, "has_description": true }, "components": [ { "key": "readme", "name": "README", "detail": null, "points": 30, "status": "met", "details": [], "max_points": 30 }, { "key": "documentation_directory", "name": "Documentation directory", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 25 }, { "key": "documentation_homepage_site", "name": "Documentation / homepage site", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 15 }, { "key": "repository_description", "name": "Repository description", "detail": null, "points": 10, "status": "met", "details": [], "max_points": 10 }, { "key": "topics", "name": "Topics", "detail": "3 topics", "points": 10, "status": "met", "details": [ { "code": "topics_count", "params": { "count": 3 } } ], "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": 61, "weight": 0.16, "metrics": [ { "key": "security_posture", "band": "moderate", "name": "Security posture", "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "signed_releases" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 61, "inputs": { "source": "openssf_scorecard", "checks_evaluated": 17, "scorecard_version": "v5.5.0", "checks_inconclusive": 1, "scorecard_aggregate": 6.1 }, "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": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "cii_best_practices", "name": "CII-Best-Practices", "detail": "no effort to earn an OpenSSF best practices badge detected", "points": 0, "status": "missed", "details": [], "max_points": 2.5 }, { "key": "code_review", "name": "Code-Review", "detail": "Found 1/30 approved changesets -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 7.5 }, { "key": "contributors", "name": "Contributors", "detail": "project has 14 contributing companies or organizations", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "dangerous_workflow", "name": "Dangerous-Workflow", "detail": "no dangerous workflow patterns detected", "points": 10, "status": "met", "details": [], "max_points": 10 }, { "key": "dependency_update_tool", "name": "Dependency-Update-Tool", "detail": "update tool detected", "points": 7.5, "status": "met", "details": [], "max_points": 7.5 }, { "key": "fuzzing", "name": "Fuzzing", "detail": "project is not fuzzed", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "license", "name": "License", "detail": "license file detected", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "maintained", "name": "Maintained", "detail": "30 commit(s) and 30 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": "all dependencies are pinned", "points": 5, "status": "met", "details": [], "max_points": 5 }, { "key": "sast", "name": "SAST", "detail": "SAST tool is not run on all commits -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "security_policy", "name": "Security-Policy", "detail": "security policy file not detected", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "signed_releases", "name": "Signed-Releases", "detail": "no releases found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 7.5 }, { "key": "token_permissions", "name": "Token-Permissions", "detail": "detected GitHub workflow tokens with excessive permissions", "points": 0, "status": "missed", "details": [], "max_points": 7.5 }, { "key": "vulnerabilities", "name": "Vulnerabilities", "detail": "0 existing vulnerabilities detected", "points": 7.5, "status": "met", "details": [], "max_points": 7.5 } ] }, { "key": "high_risk_jurisdiction_exposure", "band": "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": 21 }, "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": 64, "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": "100 of 100 human commits state their intent (structured subject or explanatory body)", "points": 40, "status": "met", "details": [ { "code": "legible_history", "params": { "legible": 100, "sampled": 100 } } ], "max_points": 40 } ] }, { "key": "ai_verify_loop", "band": "excellent", "name": "Verify loop (build / test / typecheck)", "note": null, "notes": [], "value": 81, "inputs": { "has_nix": false, "has_tests": true, "lockfiles": [], "has_dockerfile": false, "typed_language": true, "bootstrap_files": [], "has_devcontainer": true, "has_linter_config": false, "typecheck_configs": [], "agent_commit_share": 0.86, "toolchain_manifests": [ "Cargo.toml", "parser/Cargo.toml", "sdd/Cargo.toml" ], "dependency_bot_commit_share": 0 }, "components": [ { "key": "one_command_bootstrap", "name": "One-command bootstrap", "detail": "Cargo.toml, parser/Cargo.toml, sdd/Cargo.toml (toolchain convention, no task runner)", "points": 12.6, "status": "partial", "details": [ { "code": "toolchain_convention", "params": { "files": "Cargo.toml, parser/Cargo.toml, sdd/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": "devcontainer", "points": 10, "status": "met", "details": [ { "code": "file_list", "params": { "files": "devcontainer" } } ], "max_points": 10 }, { "key": "demonstrated_agent_practice", "name": "Demonstrated agent practice", "detail": "86 of the last 100 commits agent-authored or agent-credited", "points": 10, "status": "met", "details": [ { "code": "agent_authored_commits", "params": { "count": 86, "sampled": 100 } } ], "max_points": 10 }, { "key": "automated_maintenance", "name": "Automated maintenance", "detail": "dependency automation configured, none observed in the sampled commits", "points": 5, "status": "partial", "details": [ { "code": "dependency_bot_config_only", "params": {} } ], "max_points": 8 }, { "key": "openssf_scorecard_pinned_dependencies", "name": "OpenSSF Scorecard: Pinned-Dependencies", "detail": "all dependencies are pinned", "points": 10, "status": "met", "details": [], "max_points": 10 } ] }, { "key": "ai_code_legibility", "band": "exceptional", "name": "Code legibility for models", "note": null, "notes": [], "value": 94, "inputs": { "primary_language": "Rust", "largest_source_bytes": 434972, "source_files_sampled": 419, "oversized_source_files": 45 }, "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": "45/419 source files over 60KB", "points": 49.1, "status": "partial", "details": [ { "code": "oversized_source_files", "params": { "kb": 60, "sampled": 419, "oversized": 45 } } ], "max_points": 55 } ] }, { "key": "ai_interfaces", "band": "weak", "name": "Machine-readable interfaces", "note": null, "notes": [], "value": 40, "inputs": { "example_dirs": [ "examples" ], "has_mcp_signal": false, "api_schema_files": [] }, "components": [ { "key": "api_schema_openapi_graphql_proto", "name": "API schema (OpenAPI/GraphQL/proto)", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 40 }, { "key": "mcp_server", "name": "MCP server", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 20 }, { "key": "runnable_examples", "name": "Runnable examples", "detail": "examples", "points": 40, "status": "met", "details": [ { "code": "file_list", "params": { "files": "examples" } } ], "max_points": 40 } ] } ], "description": "How well is the repo equipped to be developed and maintained with AI coding agents? 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" ], "labels": [ "library" ], "scores": { "library": 6 }, "primary": "library", "evidence": [ { "tier": "distribution", "label": "library", "source": "registry:crates", "weight": 6 } ], "artifacts": [], "confidence": "medium", "host_extension": false, "runs_as_process": false, "consumed_by_code": true }, "metrics_version": "2.5.0" }, "warnings": [ "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token", "crates package 'sdd' points at a different repository (https://codeberg.org/wvwwvwwv/scalable-delayed-dealloc); excluded from ecosystem scoring", "deps.dev does not index crates:asciidoc-parser@0.29.4; advisories assessed against the repository dependency graph instead", "No resolved dependencies carried a version and a supported ecosystem" ], "report_type": "repository", "generated_at": "2026-08-01T18:22:10.907697Z", "schema_version": "0.27.0", "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/asciidoc-rs/asciidoc-parser.svg", "full_name": "asciidoc-rs/asciidoc-parser", "license_state": "standard", "license_spdx": "Apache-2.0" }, "repoMeta": null, "notFound": false, "related": [ { "id": 36269, "full_name": "markedjs/marked", "url": "https://github.com/markedjs/marked", "description": "A markdown parser and compiler. Built for speed.", "ecosystem": "npm", "ecosystems": [ "npm" ], "primary_language": "JavaScript", "languages": [ "JavaScript", "TypeScript", "HTML" ], "topics": [ "markdown", "compiler", "parser", "commonmark", "gfm", "hacktoberfest", "markup", "html" ], "license_spdx": null, "license_state": "custom", "stars": 37026, "forks": 3613, "watchers": 381, "monthly_downloads": 242534193, "latest_score": 98, "latest_band": "exceptional", "latest_scanned_at": "2026-08-04T19:43:46.054715Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "maintained", "red_flags": [], "icon_url": "/icon/v1/markedjs/marked?v=6c02a7bf-1", "icon_source_type": "homepage", "badge_url": "" }, { "id": 9140, "full_name": "oxc-project/oxc", "url": "https://github.com/oxc-project/oxc", "description": "⚓ A collection of high-performance JavaScript tools.", "ecosystem": "crates", "ecosystems": [ "crates", "npm" ], "primary_language": "Rust", "languages": [ "Rust" ], "topics": [ "compiler", "javascript", "linter", "minifier", "parser", "typescript", "transpiler", "development-tools", "compilers", "web-programming" ], "license_spdx": "MIT", "license_state": "standard", "stars": 22220, "forks": 1171, "watchers": 85, "monthly_downloads": 1521396, "latest_score": 97, "latest_band": "exceptional", "latest_scanned_at": "2026-08-05T04:02:02.798361Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "maintained", "red_flags": [], "icon_url": "/icon/v1/oxc-project/oxc?v=de80ce08-1", "icon_source_type": "homepage", "badge_url": "" }, { "id": 44230, "full_name": "wasmerio/wasmer", "url": "https://github.com/wasmerio/wasmer", "description": "🚀 Fast, secure, lightweight containers based on WebAssembly", "ecosystem": "crates", "ecosystems": [ "crates" ], "primary_language": "Rust", "languages": [ "Rust" ], "topics": [ "webassembly", "wasm", "wasi", "emscripten", "rust", "windows", "macos", "linux", "wasmer", "wasix", "runtime", "vm", "cli", "command-line-interface", "api-bindings", "cache", "caching", "types", "data-structures", "no-std", "toml", "parser-implementations" ], "license_spdx": "MIT", "license_state": "standard", "stars": 20940, "forks": 989, "watchers": 194, "monthly_downloads": 727452, "latest_score": 96, "latest_band": "exceptional", "latest_scanned_at": "2026-08-05T04:21:24.420344Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "maintained", "red_flags": [], "icon_url": "/icon/v1/wasmerio/wasmer?v=bf05dcc7-1", "icon_source_type": "homepage", "badge_url": "" }, { "id": 18476, "full_name": "biomejs/biome", "url": "https://github.com/biomejs/biome", "description": "A toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.", "ecosystem": "crates", "ecosystems": [ "crates", "npm" ], "primary_language": "Rust", "languages": [ "Rust" ], "topics": [ "css", "formatter", "javascript", "jsx", "linter", "static-code-analysis", "typescript", "web", "json", "parser", "development-tools", "web-programming" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 25498, "forks": 1175, "watchers": 98, "monthly_downloads": 233173, "latest_score": 96, "latest_band": "exceptional", "latest_scanned_at": "2026-08-05T03:11:12.534840Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "maintained", "red_flags": [], "icon_url": "/icon/v1/biomejs/biome?v=bf585c67-1", "icon_source_type": "homepage", "badge_url": "" }, { "id": 3036, "full_name": "swc-project/swc", "url": "https://github.com/swc-project/swc", "description": "Rust-based platform for the Web", "ecosystem": "crates", "ecosystems": [ "crates" ], "primary_language": "Rust", "languages": [ "Rust" ], "topics": [ "ecmascript", "compiler", "rust", "javascript", "parser", "babel", "swc", "ecmascript-parser", "typescript", "typescript-compiler", "typescript-parser" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 34163, "forks": 1533, "watchers": 182, "monthly_downloads": 1246493, "latest_score": 96, "latest_band": "exceptional", "latest_scanned_at": "2026-08-05T01:26:43.411729Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "maintained", "red_flags": [], "icon_url": "/icon/v1/swc-project/swc?v=400c5222-1", "icon_source_type": "homepage", "badge_url": "" }, { "id": 1517, "full_name": "tree-sitter/tree-sitter", "url": "https://github.com/tree-sitter/tree-sitter", "description": "An incremental parsing system for programming tools", "ecosystem": "crates", "ecosystems": [ "crates" ], "primary_language": "Rust", "languages": [ "Rust", "C" ], "topics": [ "incremental", "parsing", "tree-sitter", "rust", "parser", "wasm", "external-ffi-bindings", "api-bindings", "text-editors" ], "license_spdx": "MIT", "license_state": "standard", "stars": 26539, "forks": 2797, "watchers": 284, "monthly_downloads": 3981552, "latest_score": 95, "latest_band": "exceptional", "latest_scanned_at": "2026-08-05T02:50:54.012090Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "maintained", "red_flags": [], "icon_url": "/icon/v1/tree-sitter/tree-sitter?v=a07c055f-1", "icon_source_type": "avatar", "badge_url": "" } ] } }
Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 2.5.0 · 2026-08-01 18:22 UTC

asciidoc-rs / asciidoc-parser

AsciiDoc parser

Rust · RubyApache-2.0★ 34 Sterne⑂ 4 Forksseit Dez. 2023Auf GitHub ansehen ↗

asciidoc-rs/asciidoc-parser erreicht einen Gesundheitsindex von 77 von 100 und liegt damit im Bereich Gut. Am stärksten schneidet es bei Vitality (94/100) ab, am schwächsten bei Community & Adoption (43/100). Zuletzt heute aktualisiert. 2 Mitwirkende tragen den Großteil der jüngsten Arbeit.

77
gesamt / 100
Gut

Software-Gesundheitsindex

Metriken werden auf einer standardisierten Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr gewichtetes Mittel, kalibriert auf die Verteilung des öffentlichen Registers, sodass die Stufen Perzentilbedeutung tragen; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze Gefährdet von 34.

77
Außergewöhnlich93-100Die Spitzengruppe des Registers (≈ obere 5 %); erfüllt im Wesentlichen alle geprüften Kriterien
Exzellent80-92Durchgehend stark; geringfügige Lücken
Gut65-79Gesund; Lücken sind begrenzt und beherrschbar
Mittel50-64Akzeptabel mit deutlichen Lücken; Überprüfung empfohlen
Schwach35-49Wesentliche Schwächen in mehreren Bereichen
Gefährdet20-34Erhebliche Schwächen; eine Übernahme erfordert Vorsicht
Kritisch1-19Schwerwiegende Probleme (aufgegeben, nur ein Maintainer, keine Hygiene)
VitalitätCommunity &VerbreitungNachhaltigkeit &GovernanceEngineering-QualitätSicherheitAI Readiness

Bewertungsprofil

Jede Achse ist eine Kategorie. Die Form zählt mehr als der Durchschnitt — ein gesundes Projekt füllt die gesamte Fläche, während ein Profil aus Spitzen und Kratern bedeutet, dass Stärke in einer Dimension Risiken in einer anderen verdeckt.

Der gewichtete Gesamtwert 66 wird auf der veröffentlichten Indexskala auf 77 kalibriert (Register-Kalibrierung 2026-08-02).

Eigentümerschaft

Asciidoc in RustOrganisation
0 Follower2 öffentliche Reposseit Feb. 2026

Dieses Repository wird von einer Organisation getragen — geteilte, rechenschaftspflichtige Trägerschaft, die jeden einzelnen Maintainer überdauern kann.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlichtTags
crates.iosddverweist auf ein anderes Repo — nicht bewertet4.8.85.899.17372vor 30 Tagenconcurrentgarbagememoryepochlock-freedata-structuresconcurrencymemory-management
crates.ioasciidoc-parser0.29.42.01255vor 0 Tagenparserasciidocparser-implementations

Metriken nach Kategorie

Vitalität

Lebt das Projekt — wird Code geschrieben und werden Releases ausgeliefert?

94Außergewöhnlich · 21 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 0 Tagen
25.6/36Commit-Rhythmus — 37/52 Wochen mit Commits
18/18Commit-Volumen — 546 Commits im letzten Jahr
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
Verwendete Eingangsdaten
commits_last_year546
human_commit_share1
days_since_last_push0
active_weeks_last_year37

Release-Disziplin

100Außergewöhnlich
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 55 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 0 Tagen
27/27Release-Rhythmus — ein Release etwa alle 0,7 Tage
0/10OpenSSF Scorecard: Signed-Releases — keine Daten
Verwendete Eingangsdaten
releases_count55
latest_release_tagv0.29.4
releases_from_tagsnein
days_since_latest_release0
mean_days_between_releases0,7
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: Signed-Releases. Die verbleibenden Gewichte wurden renormalisiert.

Community & Verbreitung

Hat das Projekt Nutzer, Downloads, Aufmerksamkeit und ein einladendes Umfeld für Beitragende?

43Schwach · 17 % des Gesamtindex
Wie die Bewertung erfolgt
24.6/60Stars — 34 Stars
4/25Forks — 4 Forks
0/15Watcher — 2 Watcher
Verwendete Eingangsdaten
forks4
stars34
watchers2
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
22.5/22.5Lizenz — anerkannte Lizenz (Apache-2.0)
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
readme_badges
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
readme_badge_services
has_pull_request_templatenein
Wie die Bewertung erfolgt
44.1/80Downloads pro Monat — 2.012 Downloads/Monat über crates
0/20Abhängige in der Registry — von diesem Ökosystem nicht ausgewiesen
Verwendete Eingangsdaten
packagesasciidoc-parser
dependents
ecosystemscrates
total_downloads13.542
monthly_downloads2.012
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Abhängige in der Registry. Die verbleibenden Gewichte wurden renormalisiert.

Nachhaltigkeit & Governance

Überdauert das Projekt die Menschen, die es tragen — Bus-Faktor, Reaktionsfähigkeit, Trägerschaft und Paketpflege?

66Gut · 23 % des Gesamtindex
Wie die Bewertung erfolgt
25.2/54Bus-Faktor — 2 Beitragende decken die Hälfte aller Commits ab
11.4/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 49 % der Commits
13.5/13.5Breite der Beitragenden — 22 Beitragende
10/10OpenSSF Scorecard: Contributors — project has 14 contributing companies or organizations
Verwendete Eingangsdaten
bus_factor2
contributors_sampled22
top_contributor_share0,492
Wie die Bewertung erfolgt
41.5/42Issue-Lösungsquote — 99 % der Issues geschlossen
28.5/30PR-Annahme — 772/812 entschiedene PRs gemergt
0/13Newcomer PR acceptance — kein PR eines Erstbeitragenden in 30 Tagen entschieden
0/15OpenSSF Scorecard: Code-Review — Found 1/30 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs772
open_issues3
closed_issues223
prs_merged_7d
prs_decided_7d
prs_merged_30d
prs_decided_30d
issue_closed_ratio0,987
closed_unmerged_prs40
first_time_authors_30d
first_time_prs_merged_30d
first_time_prs_decided_30d
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): newcomer_pr_acceptance. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
30/30Organisatorische Trägerschaft — im Besitz einer Organisation
0/20Verifizierte Domain
0/25Reichweite des Inhabers — 0 Follower von asciidoc-rs
4.4/25Kontohistorie — 2 öffentliche Repos, Kontoalter ca. 0 Jahre
Verwendete Eingangsdaten
followers0
owner_typeOrganization
is_verified
owner_loginasciidoc-rs
public_repos2
account_age_days175

Paketpflege

100Außergewöhnlich
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 1 Paket(e) auf crates
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 0 Tagen
20/20Versionshistorie — 55 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packagesasciidoc-parser
ecosystemscrates
any_deprecatednein
min_days_since_publish0

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

61Mittel · 19 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 3 Workflow(s)
24/24Tests vorhanden
0/16Linter-Konfiguration
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 30 out of 30 merged PRs checked by a CI test -- score normalized to 10
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfignein
has_linter_confignein
has_precommit_confignein
Wie die Bewertung erfolgt
30/30README
0/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
10/10Topics — 3 Topics
0/10Wiki
Verwendete Eingangsdaten
topicsasciidoc, markup, parser
has_wikinein
homepage
has_readmeja
has_docs_dirnein
has_descriptionja

Sicherheit

Sind die sichtbaren Sicherheits- und Lieferkettenpraktiken belastbar, ohne ungeklärte Exposition gegenüber Hochrisikojurisdiktionen?

61Mittel · 16 % des Gesamtindex
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
2.2/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 1/30 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 14 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Lizenz — license file detected
7.5/7.5Maintained — 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
5/5Pinned-Dependencies — all dependencies are pinned
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — keine Daten
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate6,1
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): signed_releases. Die verbleibenden Gewichte wurden renormalisiert.

AI Readiness

Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Trägt ein bewusst kleines Gewicht (4 %): Agenten-Tooling ist ein echtes Pflegesignal, doch ein Repository ohne jedes Signal kann weiterhin 100/100 erreichen.

64Mittel · 4 % des Gesamtindex
Wie die Bewertung erfolgt
0/45Agentenanweisungen — keine CLAUDE.md / AGENTS.md / Editor-Regeln
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 100 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share1
agent_instruction_files
agent_instruction_max_bytes
Wie die Bewertung erfolgt
12.6/18Bootstrap mit einem Befehl — Cargo.toml, parser/Cargo.toml, sdd/Cargo.toml (Toolchain-Konvention, kein Task-Runner)
22/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
11/11Statische Typprüfung — Rust (statisch typisiert)
10/10Reproduzierbare Umgebung — devcontainer
10/10Belegte Agentenpraxis — 86 der letzten 100 Commits von Agenten verfasst oder ihnen zugeschrieben
5/8Automatisierte Wartung — Abhängigkeits-Automatisierung konfiguriert, in den erfassten Commits nicht beobachtet
10/10OpenSSF Scorecard: Pinned-Dependencies — all dependencies are pinned
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfiles
has_dockerfilenein
typed_languageja
bootstrap_files
has_devcontainerja
has_linter_confignein
typecheck_configs
agent_commit_share0,86
toolchain_manifestsCargo.toml, parser/Cargo.toml, sdd/Cargo.toml
dependency_bot_commit_share0
Wie die Bewertung erfolgt
45/45Typprüfbarer Code — Rust (statisch typisiert)
49.1/55Handhabbare Dateigrößen — 45/419 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageRust
largest_source_bytes434.972
source_files_sampled419
oversized_source_files45
Wie die Bewertung erfolgt
0/40API-Schema (OpenAPI/GraphQL/proto)
0/20MCP-Server
40/40Lauffähige Beispiele — examples
Verwendete Eingangsdaten
example_dirsexamples
has_mcp_signalnein
api_schema_files

Eckdaten

34GitHub-Sterne
22Mitwirkende
546Commits, letzte 12 Monate
0Tage seit letztem Push
55Releases
2Bus-Faktor
3offene Issues
crates.ioPaket-Ökosysteme

Warnungen zur Datenerhebung

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • crates package 'sdd' points at a different repository (https://codeberg.org/wvwwvwwv/scalable-delayed-dealloc); excluded from ecosystem scoring
  • deps.dev does not index crates:asciidoc-parser@0.29.4; advisories assessed against the repository dependency graph instead
  • No resolved dependencies carried a version and a supported ecosystem

Weitere Details

Stern- und Fork-Verlauf 0 ★ / 4 ⇿
0Sterne
4Forks
20Releases

Wann jeder Stern und Fork hinzugefügt wurde, von GitHub erfasst und nach Tagen gruppiert. Das kumulierte Wachstum steht direkt über den täglichen Zugängen, aus denen es besteht, sodass beide gegeneinander lesbar sind: stetiger organischer Zuwachs sieht ganz anders aus als ein abrupter, kurzlebiger Ausschlag. Wo dieser Unterschied messbar ist, wird er als Wachstumsauthentizität ausgewiesen.

1223344412026-012026-042026-07
Major 0Minor 9Patch 11
OpenSSF Scorecard 6.1 / 10
6.1Gesamtwert

Unabhängige, werkzeugneutrale Sicherheitsbewertung durch das quelloffene OpenSSF Scorecard. Jede Prüfung honoriert eine Sicherheits-Praxis, nicht das Werkzeug eines bestimmten Anbieters. Prüfungen, die Scorecard nicht ermitteln konnte, sind mit k. A. markiert und vom Sicherheitswert ausgeschlossen (nie als null gezählt).Scorecard v5.5.0 · 2026-08-01 18:21 UTC

10Binary-Artifactsno binaries found in the repo
3Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests30 out of 30 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 1/30 approved changesets -- score normalized to 0
10Contributorsproject has 14 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
10Pinned-Dependenciesall dependencies are pinned
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
k. A.Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Direkte Abhängigkeiten 7
RegistryPaketVersionsvorgabeManifest
crates.iobytecount0.6.7parser/Cargo.toml
crates.iomemchr2.6.4parser/Cargo.toml
crates.iopercent-encoding2.3.2parser/Cargo.toml
crates.ioregex1.11.1parser/Cargo.toml
crates.ioself_cell1.2.0parser/Cargo.toml
crates.iothiserror2.0.1parser/Cargo.toml
crates.iowalkdir2.5sdd/Cargo.toml
Alle Abhängigkeiten 10

Vollständig aufgelöster Abhängigkeitssatz aus dem GitHub-Abhängigkeitsgraphen: 7 direkte und 3 indirekte (transitive) Pakete. Die transitive Hülle ist vollständig, wenn das Repository eine Lockfile eincheckt.

RegistryPaketVersionBeziehung
crates.iobytecountdirekt
crates.iomemchrdirekt
crates.iopercent-encodingdirekt
crates.ioregexdirekt
crates.ioself_celldirekt
crates.iothiserrordirekt
crates.iowalkdirdirekt
crates.iocodspeed-criterion-compatindirekt
crates.iocriterionindirekt
crates.iopretty_assertions_sortedindirekt
Abhängigkeits-Advisories nicht bewertet

Der Advisory-Abgleich konnte für diesen Bericht nicht ausgeführt werden: No resolved dependencies carried a version and a supported ecosystem

JSON-Rohbericht maschinenlesbar
{
  "data": {
    "repo": {
      "topics": [
        "asciidoc",
        "markup",
        "parser"
      ],
      "is_fork": false,
      "size_kb": 10362,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "Ruby": 1365426,
        "Rust": 9173981
      },
      "pushed_at": "2026-08-01T18:18:34Z",
      "created_at": "2023-12-08T22:28:07Z",
      "owner_type": "Organization",
      "updated_at": "2026-08-01T17:53:52Z",
      "description": "AsciiDoc parser",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "Rust",
      "significant_languages": [
        "Rust",
        "Ruby"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Asciidoc in Rust",
      "type": "Organization",
      "login": "asciidoc-rs",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/259974080?v=4",
      "created_at": "2026-02-06T23:44:44Z",
      "is_verified": null,
      "public_repos": 2,
      "account_age_days": 175
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.29.4",
          "kind": "patch",
          "published_at": "2026-08-01T16:14:24Z"
        },
        {
          "tag": "v0.29.3",
          "kind": "patch",
          "published_at": "2026-08-01T15:12:16Z"
        },
        {
          "tag": "v0.29.2",
          "kind": "patch",
          "published_at": "2026-08-01T03:07:56Z"
        },
        {
          "tag": "v0.29.1",
          "kind": "patch",
          "published_at": "2026-07-31T16:04:51Z"
        },
        {
          "tag": "v0.29.0",
          "kind": "minor",
          "published_at": "2026-07-30T11:59:36Z"
        },
        {
          "tag": "v0.28.1",
          "kind": "patch",
          "published_at": "2026-07-29T04:41:03Z"
        },
        {
          "tag": "v0.28.0",
          "kind": "minor",
          "published_at": "2026-07-29T01:56:13Z"
        },
        {
          "tag": "v0.27.4",
          "kind": "patch",
          "published_at": "2026-07-27T19:11:27Z"
        },
        {
          "tag": "v0.27.3",
          "kind": "patch",
          "published_at": "2026-07-27T14:34:35Z"
        },
        {
          "tag": "v0.27.2",
          "kind": "patch",
          "published_at": "2026-07-26T18:15:58Z"
        },
        {
          "tag": "v0.27.1",
          "kind": "patch",
          "published_at": "2026-07-25T20:45:30Z"
        },
        {
          "tag": "v0.27.0",
          "kind": "minor",
          "published_at": "2026-07-25T04:26:16Z"
        },
        {
          "tag": "v0.26.0",
          "kind": "minor",
          "published_at": "2026-07-24T15:53:14Z"
        },
        {
          "tag": "v0.25.0",
          "kind": "minor",
          "published_at": "2026-07-23T15:22:02Z"
        },
        {
          "tag": "v0.24.0",
          "kind": "minor",
          "published_at": "2026-07-23T04:34:34Z"
        },
        {
          "tag": "v0.23.4",
          "kind": "patch",
          "published_at": "2026-07-18T16:01:38Z"
        },
        {
          "tag": "v0.23.3",
          "kind": "patch",
          "published_at": "2026-07-16T03:42:30Z"
        },
        {
          "tag": "v0.23.2",
          "kind": "patch",
          "published_at": "2026-07-16T00:51:13Z"
        },
        {
          "tag": "v0.23.1",
          "kind": "patch",
          "published_at": "2026-07-15T04:54:15Z"
        },
        {
          "tag": "v0.23.0",
          "kind": "minor",
          "published_at": "2026-07-14T15:11:44Z"
        },
        {
          "tag": "v0.22.1",
          "kind": "patch",
          "published_at": "2026-07-13T04:20:21Z"
        },
        {
          "tag": "v0.22.0",
          "kind": "minor",
          "published_at": "2026-07-13T02:50:59Z"
        },
        {
          "tag": "v0.21.0",
          "kind": "minor",
          "published_at": "2026-07-12T16:06:19Z"
        },
        {
          "tag": "v0.20.0",
          "kind": "minor",
          "published_at": "2026-07-12T02:15:00Z"
        },
        {
          "tag": "v0.19.2",
          "kind": "patch",
          "published_at": "2026-07-11T16:10:24Z"
        },
        {
          "tag": "v0.19.1",
          "kind": "patch",
          "published_at": "2026-07-10T15:21:10Z"
        },
        {
          "tag": "v0.19.0",
          "kind": "minor",
          "published_at": "2026-07-05T04:01:37Z"
        },
        {
          "tag": "v0.18.0",
          "kind": "minor",
          "published_at": "2026-07-04T21:17:01Z"
        },
        {
          "tag": "v0.17.0",
          "kind": "minor",
          "published_at": "2026-06-30T13:52:23Z"
        },
        {
          "tag": "v0.16.0",
          "kind": "minor",
          "published_at": "2026-06-29T20:57:15Z"
        },
        {
          "tag": "v0.15.2",
          "kind": "patch",
          "published_at": "2026-06-29T14:39:19Z"
        },
        {
          "tag": "v0.15.1",
          "kind": "patch",
          "published_at": "2026-06-20T00:28:43Z"
        },
        {
          "tag": "v0.15.0",
          "kind": "minor",
          "published_at": "2026-06-19T01:21:07Z"
        },
        {
          "tag": "v0.14.5",
          "kind": "patch",
          "published_at": "2026-06-18T04:38:17Z"
        },
        {
          "tag": "v0.14.4",
          "kind": "patch",
          "published_at": "2026-03-07T16:38:47Z"
        },
        {
          "tag": "v0.14.3",
          "kind": "patch",
          "published_at": "2026-01-25T01:19:57Z"
        },
        {
          "tag": "v0.14.2",
          "kind": "patch",
          "published_at": "2026-01-17T20:00:18Z"
        },
        {
          "tag": "v0.14.1",
          "kind": "patch",
          "published_at": "2026-01-02T02:48:33Z"
        },
        {
          "tag": "v0.14.0",
          "kind": "minor",
          "published_at": "2025-12-08T04:33:46Z"
        },
        {
          "tag": "v0.13.1",
          "kind": "patch",
          "published_at": "2025-11-17T00:30:53Z"
        },
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2025-11-16T02:12:01Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2025-11-15T01:04:20Z"
        },
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2025-11-02T21:47:12Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2025-10-15T02:27:11Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2025-10-12T23:17:56Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2025-10-10T05:04:40Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2025-09-18T04:35:20Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2025-09-08T05:10:31Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2025-08-16T20:42:11Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2025-04-27T19:26:02Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2025-04-14T03:55:19Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2025-04-11T20:31:10Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2024-11-30T19:23:59Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2024-10-26T22:33:15Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2024-10-26T22:28:00Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "85320d8042ad10832b6e6cdc5cc7f7ef740c558f",
          "body": "A block title (`.Title`) directly above the `= …` document-title line\nmeans the line is not the document title. Asciidoctor demotes it to a\nlevel-0 section heading in the body, leaves the header empty, and logs\n\"level 0 sections can only be used when doctype is book\".\n\nv0.29.3 delivered only the car\n[…]\nning still hold. This also\nmakes a block title above `= …` at the document start behave exactly like\nthe same construct mid-body.\n\nCloses #1037\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Demote the document title when block metadata precedes it (#1038)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T17:53:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b658c8d3f19b02767dd0c0e447cb1eb9d99cfaca",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.29.4 (#1035)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T16:13:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ffb81e9641a3d6e2fa640752a81f796915ac46ca",
          "body": "…ue (#1034)\n\n* fix: Strip a trailing `@` soft-set modifier from an API attribute value\n\nA single trailing `@` on an attribute value supplied via the API (the\nAsciidoctor CLI/API soft-set modifier) is now stripped from the stored\nvalue, and the attribute is made overridable by a document `:name:` ent\n[…]\nhe crate's `#![deny(warnings)]`,\nfailing the internal-documentation CI job.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Strip a trailing `@` soft-set modifier from an API attribute val…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T16:06:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "78f8a5f0e76c29812d4ebef7263e363faf21bcc0",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.29.3 (#1031)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T15:11:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "42a8a285fe280f75443d82564a7a5de3fd064610",
          "body": "…try (#1032)\n\nA single `:author:` attribute entry populated `author` (and the derived\n`firstname`, `lastname`, `authorinitials`, …) inline but never set the\ncombined `authors` attribute, so `{authors}` rendered empty. The implicit\nauthor line and the `:authors:` / indexed `:author_N:` forms all set \n[…]\n is done inline rather\nthan through `set_author_metadata` so an explicit `:authorinitials:`\noverride on this path still survives.\n\nCloses #1027\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Set the combined `authors` attribute from a single `:author:` en…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T15:05:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e9d97bc5912e51fe49857cff17e1ab4c3cfaebf1",
          "body": "…ent (#1030)\n\n* fix: Treat a section heading inside a delimited block as literal content\n\nA `== …` line inside a delimited block (an example `====`, sidebar\n`****`, or open `--` block, a quote `____` block, or a Markdown-style\nblockquote) was parsed as a real section. Asciidoctor only recognizes\nsec\n[…]\nary, so cell sections are recognized\nregardless of where the table appears.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Treat a section heading inside a delimited block as literal cont…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T05:04:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0c5621ec0f21620d893fe4192b4959fdc30b04fc",
          "body": "…le (#1028)\n\n* fix: Coerce a leveloffset-shifted level-0 heading to the document title\n\nWhen a `:leveloffset:` shift drives a heading to effective level 0, that\nheading is now coerced to the document title (doctitle), mirroring\nAsciidoctor's `is_next_line_doctitle?`. Previously the offset was applie\n[…]\nvel-1 section by the body parser. Add a test for\nthe tab-delimited variant.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Coerce a leveloffset-shifted level-0 heading to the document tit…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T04:07:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "761ebf78f9ee3f31e795c4b28f076f1d69b03e04",
          "body": "…rally (#1026)\n\n* fix: Ignore an empty block anchor `[[]]` instead of rendering it literally\n\nAn empty bracketed block anchor (`[[]]`) on its own line above a block\nnames nothing. Asciidoctor drops it; this crate was instead leaving the\nline in place, so it rendered as a literal `[[]]` paragraph bef\n[…]\n\nblock\". Adds regression tests for both the open-block and lone-body forms.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Ignore an empty block anchor `[[]]` instead of rendering it lite…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T04:00:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e271a290c583a186e10746842cf1da59511c2a3e",
          "body": "…adata (#1029)\n\nA block title line (`.Title`) directly above the document title (`= …`)\nwas not recognized in the document header. It fell through to the block\nparser, which attached the block title to a paragraph whose text was the\nescaped `= …` line, so the title was rendered as literal paragraph \n[…]\ncument title as a level-0 section, so it keeps `= …` as the\ndocument title. The block-title recognition and carryover are shared.\n\nCloses #1022\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Recognize a block title above the document title as document met…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T03:44:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0f9585ba016d1ff540d1d9c9574596be7dd5f66a",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.29.2 (#1019)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T03:07:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c50dc8ee7b4013ff083fa029389485ec1cc93497",
          "body": "… include (#1021)\n\nAn `IncludeFileHandler` that finds and reads a file which is not valid UTF-8\nand cannot be transcoded (no `encoding` attribute, or one it does not support)\npreviously had to return `IncludeResolution::NotFound`, misreporting the cause\nas \"include file not found\".\n\nAdd an `IncludeR\n[…]\ntor's fatal\n`invalid byte sequence in UTF-8` does.\n\nBoth types are `#[non_exhaustive]`, so the additions are backward compatible.\n\nCloses #1020\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Add IncludeResolution::NotDecodable for a found-but-undecodable…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T03:03:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1d7839bdd1d89446284ec87256f5b36ca56bcbee",
          "body": "…tains a nested section (#1017)\n\n* fix: Emit a warning when a special section that doesn't support subsections contains a nested section\n\nSpecial sections such as `glossary`, `bibliography`, `colophon`,\n`dedication`, and `index` do not support nested sections. Asciidoctor\nlogs an error (e.g. `glossa\n[…]\ntion. Adds a regression\ntest covering metadata above the offending heading.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Warn when a special section that doesn't support subsections con…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T02:52:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bca694ba89c7379d20d85c637ff74cfcc8b9e1d6",
          "body": "…te heading (#1018)\n\n* fix: Treat a `[float]`/`[discrete]` level-0 (`=`) heading as a discrete heading\n\nA `[float]`/`[discrete]` style on a level-0 (`=`) heading was promoted to\nthe document title and dropped from the block stream, instead of yielding a\ndiscrete floating-title block. Discrete headin\n[…]\nstyles_gate_doctitle_by_effective_style` covering both\noverride directions.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Treat a `[float]`/`[discrete]` level-0 (`=`) heading as a discre…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T02:47:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c603302bcfad4510b3a679cf89ff8da3ff091b8a",
          "body": "…tring (#1016)\n\nWhen an indexed `:author_N:` attribute entry overrode one author of a\nmulti-author implicit author line, the individual `author_N` attribute was\nupdated but the combined `authors` string (and `Document::authors()`) still\nreflected the original, un-overridden author.\n\n`resolve_authors\n[…]\nluding `authors` and `authorcount` –\nso `{authors}`, `Document::authors()`, and the resolved author list all\nreflect the override.\n\nclose #1013\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Reflect an indexed :author_N: override in the combined authors s…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-08-01T02:28:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e89e7584b1fcb5e57c26f93cfb2c19db6795908c",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.29.1 (#1010)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-31T16:04:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e4a74f7f3a1577667e4799d3375967953dcbd9c3",
          "body": "…artitioning (#1009)\n\n* fix: Run :author: attribute value through substitutions before name partitioning\n\nAsciidoctor substitutes an attribute-entry value (via\napply_attribute_value_subs) before process_authors partitions it into name\nparts. Two gaps caused asciidoc-parser to partition the raw, unsu\n[…]\n test documenting\nthis so the behavior is not mistaken for a dropped email.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Run :author: attribute value through substitutions before name p…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-31T16:00:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "02f4349b53e3db823a69cd0f17901d36cb49ac8a",
          "body": "…-line (#1012)\n\n* fix: Emit a diagnostic for each line dropped under attribute-missing=drop-line\n\nWhen `attribute-missing` is set to `drop-line`, the parser correctly drops\nthe offending line (or blanks a header attribute value), but until now it\nrecorded no diagnostic, so a caller had no way to obs\n[…]\nion. Adds a\nregression test parsing `['{missing}']++x++` under `drop-line`.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Emit a diagnostic for lines dropped under attribute-missing=drop…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-31T15:55:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b90ac8ae62f5ecb447c4ec19f32cb14d1a4a969e",
          "body": "…mplicit author line (#1007)\n\n* fix: Populate combined `authors` and `author_1` attributes from the implicit author line\n\nFor an implicit author line, Asciidoctor exposes a combined, comma-joined\n`authors` attribute and, when more than one author is present, the first\nauthor's attributes under both \n[…]\nts\nthe header-metadata hash cardinality, which this crate does not surface.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Populate combined `authors` and `author_1` attributes from the i…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-31T15:26:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "58f6b79043c04bec341acf4a0b75cd60f370fa19",
          "body": "…hor line (#1006)\n\n* fix: Reconcile an explicit `:authors:` entry against the implicit author line\n\nWhen an explicit `:authors:` attribute entry follows an implicit author\nline, Asciidoctor reconciles the two: if the entry's value does not match\nthe computed (comma-joined) value of the implicit list\n[…]\nfail loudly rather than silently\ndiverge from the reference implementation.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Reconcile an explicit `:authors:` entry against the implicit aut…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-31T14:23:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4fec22bf196eb4301d38061c9b461c2b267e45a2",
          "body": "…#1008)\n\nSurface the inline passthroughs (`+++…+++`, `++…++`, `$$…$$`, `pass:[…]`,\ninline STEM macros) that the substitution pipeline extracts from a block's\ncontent, so downstream consumers can assert – for each extracted\npassthrough – its stored (unescaped) text and its resolved substitution\nlist,\n[…]\nbs()`. `SubstitutionGroup::steps()` is now public too, so\nthe resolved, ordered substitution steps for an entry are inspectable.\n\nCloses #1002.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Expose the inline passthrough collection on a block's content (…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-31T04:34:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6996bed96d60c872081c8efd442906613462d0ce",
          "body": "* chore(asciidoc-parser): release v0.29.0\n\n* docs(changelog): describe the #999 breaking change and migration for v0.29.0\n\nAdd a \"Breaking changes\" section to the 0.29.0 entry explaining the\nIncludeFileHandler::resolve_target reshape (Option<IncludeContent> ->\nIncludeResolution) and how to migrate a handler, matching the prose\nstyle used for earlier breaking releases.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.29.0 (#1001)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-30T11:58:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1059e9b9204bfa72649ee9ca7fc463c8fa2f2763",
          "body": "…(#1000)\n\nThe release_commits regex required the commit type to be immediately\nfollowed by `(` or `:`, so a scopeless breaking-change commit such as\n`feat!:` did not match. This meant release-plz reported \"no commit\nmatches the release commit regex\" and skipped opening a release PR\nafter #999.\n\nAdd an optional `!` before the `(`/`:` so all Conventional Commit\nforms – including `feat!:` and `fix!:` – trigger a release.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Match breaking-change commits (feat!:) in release_commits regex …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-30T11:51:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8a274b3472c985f8d83a9659eb0c843307e16d09",
          "body": "* feat!: Distinguish an unreadable include file from a missing one\n\nWhen an `include::` directive names a file that exists but cannot be\nread (e.g. a permission error), the parser previously reported it\nidentically to a missing file (`WarningType::IncludeFileNotFound`).\nAsciidoctor distinguishes the\n[…]\nes a compile error here rather than silently collapsing into\n  \"not found\".\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat!: Distinguish an unreadable include file from a missing one (#999)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-30T05:09:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bf90b2983c3c11bdd3438cae3c2395697d075e98",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.28.1 (#997)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-29T04:40:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fa904e123ffb8ceb69df3c74021f8eeed663d87",
          "body": "…it (#996)\n\n* fix: Keep block metadata attached when a comment sits directly above it\n\nA single-line comment (`//`) placed directly above a block-metadata line\n(an attribute list `[...]`, an anchor `[[...]]`, etc.) with no blank line\nbetween them detached that metadata from the block it decorated: t\n[…]\nary text directly above it already\nis, producing identical rendered output.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Keep block metadata attached when a comment sits directly above …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-29T04:35:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2d066e138e2a784193f5962855272b8ea675dd3b",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.28.0 (#994)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-29T01:55:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fd07c7e30a42627a85fad890feab0c4a7df08fe",
          "body": "* fix: Mirror Asciidoctor TOC position normalization\n\nResolve the `toc` family of attributes the way Asciidoctor's header\nnormalization does (`document.rb`), so the derived `toc-position` /\n`toc-placement` / `toc-class` attributes match for three inputs that\npreviously diverged:\n\n- direction shortha\n[…]\nnd\nadd a regression test covering `^`/`v`/`top`/`bottom`/`<`/`>` in a cell.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Mirror Asciidoctor TOC position normalization (#993)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-29T01:50:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9635c779449ff6a114f046eb05f8a65c30919282",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.27.4 (#991)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T19:10:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64f2b3cbe2dc2509fc0836be9053cc96311cd84b",
          "body": "…(#990)\n\nAn API/intrinsic `numbered` attribute (`ModificationContext::ApiOnly`, as the\nhtml5 converter applies `attributes: { 'numbered' => '' }`) remapped to a\n*locked* `sectnums`, and a locked `sectnums` could not be unset by a body\n`:numbered!:` — so every section rendered numbered and the mid-do\n[…]\nPI`) from `non_normative!` to verified tests, and add\nfocused parser unit tests for both directions of the flexible-attribute lock.\n\nclose #989\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Unlock an API-enabled `numbered` so a body toggle still applies …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T19:06:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c058b485333393e38211ed677dda13eb6b043e00",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.27.3 (#982)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T14:33:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8a59d4c7ae7753854ab89cc8b2f7e487c16c631f",
          "body": "Asciidoctor's `InlinePassRx` consumes one character before each inline\npassthrough it matches (its leading group absorbs the preceding\ncharacter and re-emits it). Because Ruby's `gsub` resumes scanning after\neach match, this shifts where the opening `+` lands inside a long run of\n`+` characters, par\n[…]\ntheir zero-width\nboundary. The retry path now splits on a char boundary since the\nconsumed preceding character may be multi-byte.\n\nCloses #979.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Tokenize a run of `+` around a passthrough like Asciidoctor (#988)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T14:30:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6e8550843e97f66d3060ed39e4c0306a5541b659",
          "body": "* fix: Preserve a quoted role on an inline passthrough span (#973)\n\nAn inline passthrough (or inline quoted text) whose role is enclosed in\nquotes – e.g. `['role']++text++` – dropped the role and rendered no\n`<span>`, diverging from Asciidoctor which keeps the quoted role verbatim.\n\nThe general attr\n[…]\nAsciidoctor slices at the\nfirst comma) with a unit assertion.\n\nCloses #987.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Preserve a quoted role on an inline passthrough span (#973) (#978)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T03:47:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "25fcab7ddb6a76043e5d9cd4661b32b006772692",
          "body": "…s caption (#984)\n\n* fix: Honor an empty document `caption` attribute to suppress a block's caption\n\nA document-wide `caption` attribute that is set but empty (bare `:caption:`,\nor `:caption:` with an empty value) now suppresses a captionable block's\ncaption and consumes no counter, matching Asciido\n[…]\n to\nsuch a block falls back to the block title, never a numbered signifier.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Honor an empty document `caption` attribute to suppress a block'…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T03:18:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5c4f74095a5e626626b6bf5d3b145963c49b432c",
          "body": "… mode (#985)\n\n* fix: Fall back to link macro for remote include under non-secure safe mode\n\nUnder a non-secure safe mode (`unsafe`/`safe`/`server`), a remote (URI)\n`include::` target whose `allow-uri-read` attribute is unset is a no-fetch\ncase: no network read is required, only that the target be *\n[…]\nes and\nall) as its `href`, rather than leaving `pass:c` as the destination.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Fall back to link macro for remote include under non-secure safe…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T03:17:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "95d31782df361c5ba32de2cbb5a78dba6885a0cf",
          "body": "* fix: Parse the `toc::[]` block macro as a `toc`-context block\n\nThe `toc::[]` block macro previously parsed as an ordinary paragraph\nwhose content was the literal text `toc::[]`, so a backend had no way to\ndetect the macro and render a table of contents at that position.\n\nAdd a `TocBlock` type (and\n[…]\nrget requirement into the `[` prefix check, removing an\nunreachable branch.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Parse the `toc::[]` block macro as a `toc`-context block (#986)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T03:10:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ef44687753e612ed06b8b8defcdfc836beb543c2",
          "body": "* feat: Expose an AsciiDoc table cell's own footnotes\n\nAn AsciiDoc (`a`) table cell is a nested document with its own footnote\nregistry, isolated from the main document (#544). That per-cell footnote\nlist was discarded after the cell parsed, so a renderer had no data to\nbuild the cell-local `#footno\n[…]\nop the issue reference, so no closed-issue link is\nleft behind in the code.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Expose an AsciiDoc table cell's own footnotes (#977)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T02:58:39Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e378c1bbdeda984ad62380ae8cb81500e0633fc8",
          "body": "…ks (#976)\n\nAn externally-supplied `hardbreaks` attribute (Asciidoctor's `-a hardbreaks`\n/ `attributes: { 'hardbreaks' => '' }`) did not insert a `<br>` at each\nunwrapped paragraph line, even though the same attribute set as a header\nentry (`:hardbreaks:`) or a `[%hardbreaks]` block option did.\n\nAsc\n[…]\ntutions_test` hardbreaks cases now faithfully\nuse the API attribute (as upstream does) instead of sidestepping via\n`[%hardbreaks]`.\n\nclose #974\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Honor API-supplied `hardbreaks` document attribute for line brea…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-27T02:30:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "30d60ceedd4cda1f7e52986892dfaeb656bbf7fb",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.27.2 (#971)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-26T18:15:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "151472d4b863cd82f7c1f6ccc5df57cbfc7739f7",
          "body": "…8) (#970)\n\n* fix: Resolve cross-reference to the document title to its title text\n\nA cross-reference to a document title carrying an explicit shorthand ID\n(`[#id]` above `= Title`) rendered the bracketed `[id]` fallback instead\nof the title's reference text, because the document title was never\nreg\n[…]\n ends the header, and\nthe empty `[[]]` form remains rejected.\n\nCloses #968.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Resolve cross-references to the document title (issues #965, #96…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-26T18:03:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a036061fdaa93e10bb07f518ba70b8d722366dae",
          "body": "A discrete (floating) heading — a `[float]` or `[discrete]` styled title —\nwas exposed with the block context `section`, indistinguishable from an\nordinary section by context alone. Asciidoctor models it as a block whose\ncontext is `floating_title`, which consumers rely on to (for example)\nexclude d\n[…]\n\ntype is `Discrete`, and `section` otherwise. `resolved_context` follows,\nsince neither the `float` nor `discrete` style is a built-in context.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Report `floating_title` context for discrete headings (#967)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-26T17:49:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0cfe8b98bf6136c297dd888477298b2b8decc0c3",
          "body": "…(#969)\n\nThe newest `dtolnay/rust-toolchain` (master) makes the `toolchain` input\nrequired and no longer falls back to a default. Dependabot (#964) bumped\nevery pinned SHA – including the ones tagged `# stable` and `# nightly` –\nto the single master SHA, so the jobs that relied on a tag's built-in\nd\n[…]\nss an explicit `toolchain:`\ninput so the setup is correct and stays clean under future Dependabot\nbumps (a single SHA to update).\n\nCloses #964.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: Add required `toolchain` input for dtolnay/rust-toolchain (#964) …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-26T17:42:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a288f6551831c319537370b60e507f2f1e3b235f",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.27.1 (#959)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T20:44:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "32dd76cdbcc6365ac4bf60ddb23cf87a3d388951",
          "body": "* fix: Unescape `\\{` and `\\}` in attribute reference substitution\n\nAn escaped attribute-reference brace should render as a literal brace with\nthe escaping backslash removed and the reference left unexpanded. The\nattribute-reference regex only recognized a backslash before the opening\nbrace (`\\{name}\n[…]\nan `{name}` form unexpanded, consistent with the\ncontent-substitution path.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Unescape `\\{` and `\\}` in attribute reference substitution (#963)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T20:41:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d48de8394a07d38a2f01965dee28babc4599fd6b",
          "body": "Remove the author_association (OWNER/COLLABORATOR/MEMBER) and explicit\ndependabot login checks from every job gate, relying purely on write\naccess to the primary repo via head.repo.full_name == github.repository.\nPushing a branch here already requires write access, so this covers\nmaintainers, dependabot, and agent-authored PRs alike. Fork PRs still\nawait the \"safe to test\" label.\n\nMirrors asciidoc-rs/asciidoc-html5#107.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: Rely on write access instead of author_association gates (#960)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T16:01:28Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2afd0b3a2b98bf8ad7630a4f9ca45d7849b5e48d",
          "body": "A block title whose first character is a period and is not followed by a\nspace (e.g. `..gitignore`) is now parsed as a block title with text\n`.gitignore`, matching Asciidoctor's `BlockTitleRx`\n(`^\\.(\\.?[^ \\t.]…)$`). Previously any line beginning with `..` was\nrejected as a title, so the marker line became a paragraph and the\nfollowing block lost its title.\n\nCloses #957\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Recognize block title with a leading period (`..name`) (#958)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T15:51:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "320ce4bdfac06a8ba4b9a1e1c684c0587ee43276",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.27.0 (#941)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T04:25:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aa767ff5cde506e86b4361ababa6c0266d9c44ac",
          "body": "* fix: capture block metadata on list items instead of dropping it\n\n`ListBlock::parse` built each list item with an empty `BlockMetadata`, so a\ntitle, anchor, or attribute list written directly before a list item's marker\nwas silently discarded. Worse, because the empty metadata could not parse past\n[…]\nt for them, restoring the original fast path for\nthe common paragraph case.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Capture block metadata on list items instead of dropping it (#954)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T04:22:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c4c7294195664e7d3005c7cc48796c9a2fdc9fcd",
          "body": "* chore: Pin GitHub Actions to specific commit SHAs\n\nReplace mutable version tags with pinned commit SHAs (each with a\ntrailing version comment) across ci.yml and pr_title.yml, following the\npattern already used in release.yml. Each SHA is the commit its tag or\nbranch currently resolves to. This har\n[…]\n currently resolves to) so all\nthree workflows share a single checkout SHA.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: Pin GitHub Actions to specific commit SHAs (#955)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T04:04:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b34f99e95e10c41ff93d4c26edf3ae455560998c",
          "body": "Part of the #939 TEMPORARY-marker audit. The `#[allow(...)]` attributes\nguarding test scaffolding are no longer warranted:\n\n- `assert_dom/virtual_dom.rs`: the `VirtualNode` builder helpers are now\n  used throughout the DOM assertions, so the blanket `#[allow(dead_code)]`\n  on the impl block is remov\n[…]\nunconstructed, so per the audit guidance they (and their\n  `Debug` / equality arms) are removed rather than left behind an allow.\n\nCloses #949.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: Remove consumed 'while building' scaffolding allows (#949) (#952)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T03:42:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8944d9105400fdba9e9d7fa29d266ad1ecf38818",
          "body": "…o_name (#953)\n\n`Span::take_ident` borrowed Rust's identifier definition (leading\nalphabetic/underscore, then alphanumerics/underscores) because\n\"identifier\" is not crisply defined in the AsciiDoc documentation. Its\nuse was already discouraged in favor of more specific helpers.\n\nThere was a single c\n[…]\nng digit) is now parsed and then rejected as unrecognized\nrather than rejected at the name-capture stage, with identical results.\n\nCloses #948.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: Replace Span::take_ident with spec-grounded take_block_macr…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T03:40:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "78d9373b0f7d80bbd965d48ec60c5924b6592832",
          "body": "…947) (#951)\n\nThe `Block` enum's variants have converged in size as the parser\nevolved. The two largest, `Section` (568 bytes) and `Media` (536\nbytes), now differ by only 32 bytes – far under clippy's 200-byte\n`large_enum_variant` threshold – so the lint no longer fires. The\n`#[allow]` (carried forw\n[…]\nasoning already\ndocumented on `BlockParseOutcome`).\n\nVerified with the CI invocation\n`cargo clippy --all-features --all-targets -- -Dwarnings`.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: Drop stale allow(clippy::large_enum_variant) on Block (close #…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T03:40:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "19faf3b5696dfb32a0f875f4d95ddb93db7a8706",
          "body": "Audit the code base for TEMPORARY / \"while building\" markers (excluding\n`ref` and tests quoting `ref` content) and convert the genuine ones to\nTODO comments that link to tracking issues, per #939.\n\n- List items discard block metadata (#946).\n- `Block` enum trips `clippy::large_enum_variant` (#947).\n- `Span::take_ident` uses a provisional identifier definition (#948).\n- Remove \"while building\" scaffolding allows once consumed (#949).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: replace TEMPORARY markers with issue-linked TODOs (#950)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-25T03:19:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5fdf0f42b24c7d41e72c1df86811d1789cd3eaba",
          "body": "Code-coverage review for dead code found no removable dead code: line\ncoverage is 98.79% and the compiler's dead_code lint is clean. The\nuncovered product lines are all intentional guardrails (defensive\nbranches, assertions, Debug impls, and a refactor-blocked region).\n\nThe one actionable cleanup is this stale attribute: the re-export is now\nused via crate::document::DuplicateIdError in the parser, so the\nallow(unused) suppresses nothing.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: Remove stale allow(unused) on DuplicateIdError re-export (#945)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T23:05:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4bbb8fe9f0018185442bda7a16e44b199f8a8e60",
          "body": "…haustive (#940)\n\n* feat: Derive Hash on the public AST / output types\n\nSpan, Block, Content, WarningType and the types reachable from them now\nimplement Hash, so blocks and spans can key a HashMap/HashSet and warnings can\nbe bucketed by type. ResolvedAttributes hashes an order-independent summary o\n[…]\nleValue / ModificationContext fields, all of which hold only Hashable\ndata.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Derive Hash on the public AST/output types; mark Warning non_ex…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T21:39:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a59f603280d80c729d8a0f80afdb3554901d187b",
          "body": "…pat 5.0.0 -> 5.0.1 (#938)\n\nPatch-level updates to the benchmark harness dev-dependencies. Raising the\ndeclared floors keeps the -Z direct-minimal-versions CI job on the current\npatch releases. Benchmarks compile and minimal-versions resolves cleanly.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(deps): Bump criterion 0.8.0 -> 0.8.2 and codspeed-criterion-com…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T19:03:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ca8db26179c0fe77d71e8e55b3a358fde32945af",
          "body": "* chore(asciidoc-parser): release v0.26.0\n\n* docs: Add 0.26.0 breaking changes guide to the changelog\n\nDocument the source-level migration for the four breaking changes in\n0.26.0 (block traversal #930, PathResolver-as-trait #934, rendering API\npolish #929, and the SourceMap reshape #917), mirroring the prose\nguide added for 0.23.0.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.26.0 (#916)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T15:52:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "50f68b5578c980dbfe90d73256b5b3e3e8b27f97",
          "body": "…ers (close #896) (#933)\n\n* feat: Let a custom InlineSubstitutionRenderer override only what differs (close #896)\n\nTwo changes unblock a downstream (e.g. Zola) `InlineSubstitutionRenderer`:\n\n- Give every `InlineSubstitutionRenderer` method a default body that\n  delegates to the built-in `HtmlSubstit\n[…]\n is not surprised that `render_icon` and a direct `icon_uri`\ncall disagree.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Let a custom InlineSubstitutionRenderer override only what diff…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T15:42:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "104ed44bd5ba50724bb852dbc58f9d423dcb9105",
          "body": "Warnings were deterministic but assembled by category (header, blocks,\npreprocessor, substitution, post-parse checks, then reference-resolution\nwarnings appended last), so an unresolved `include::` on an early line\ncould sort after a malformed inline macro further down, and unresolved-xref\nwarnings \n[…]\ne parse and after\na reference-resolution sweep folds its warnings in, so `warnings()` now\nyields line-ordered, still-deterministic diagnostics.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Emit document warnings in source order (close #901) (#932)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T15:06:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0202092e25f780df3441880c100fca1f2ed8082b",
          "body": "…(#936)\n\nPRs #930 (child_blocks API) and #934 (PathResolver trait) landed\nconcurrently without a rebase, leaving the with_path_resolver test\ncalling the removed Document::nested_blocks(). Point it at\nchild_blocks() to match the sibling call sites.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Repair stale nested_blocks() call left by concurrent PR landing …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T14:36:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e454b6e3c8507d1dc916f572a55b0d13de7b22ad",
          "body": "…k=self (close #919) (#927)\n\n* fix: Reject a dangerous image/icon target promoted to an href via link=self (close #919)\n\nAn `image:`/`icon:` macro whose target carries a script-capable scheme\n(`javascript:`, `vbscript:`, or a non-image `data:` such as\n`data:text/html,…`) is harmless in the `<img src\n[…]\nage data URIs and trusted embedded SVGs (the Asciidoctor-parity case) live.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Reject a dangerous image/icon target promoted to an href via lin…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T14:27:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "08944ce4a76acacdb4515e1b549df4728080162e",
          "body": "…r (close #898) (#934)\n\nPath resolution was the one extensibility seam in the crate that could not\nbe swapped: `PathResolver` was a concrete struct exposed as a `pub` by-value\nfield on `Parser`, so an Antora/Zola-style host needing custom path or URL\nrewriting (virtual filesystems, content roots, UR\n[…]\n` field is now `pub(crate) Rc<dyn PathResolver>`,\nconfigured through a new `with_path_resolver(...)` builder rather than direct\nfield mutation.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor!: Make PathResolver a trait with a with_path_resolver builde…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T14:21:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d01724d237725af16b2892d5572cc95e102b7443",
          "body": "…I (close #894) (#930)\n\n* feat!: replace IsBlock::nested_blocks with a complete child_blocks API (close #894)\n\nThe discoverable block accessor `IsBlock::nested_blocks()` silently omitted\nMarkdown-blockquote children (reachable only via `QuoteBlock::blocks()`) and\nAsciiDoc table-cell content, so tool\n[…]\nck`, and\n  the `nth` override) generated by the `opaque_slice_iter!` macro.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat!: Replace IsBlock::nested_blocks with a complete child_blocks AP…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T14:18:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6dbdb248bb87626baa8087ac7c6ef5cbc0f52de9",
          "body": "…#903) (#931)\n\n* fix: Enforce SourceMap append ordering with a debug assertion (close #903)\n\n`SourceMap::resolve` binary-searches `segments` by `output_line`, which\nsilently returns garbage on an unsorted slice. `append` documented that\nentries \"should\" arrive in increasing order but did not enforce\n[…]\nptile-apps[bot]@users.noreply.github.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>\nCo-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix: Enforce SourceMap append ordering with a debug assertion (close …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T14:14:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5cb17dc58929cd6e654764f8b50a06e222229607",
          "body": "…se #899) (#926)\n\n`Catalog::ids()` and `Catalog::entries()` iterated a randomly-seeded\n`HashMap`, so their order varied between process runs. A multi-document\npipeline that derives output from catalog iteration order (e.g. building a\nglobal cross-reference index, or resolving a collision as \"first s\n[…]\nookups. `DebugHashMapFrom` is generalized to render either map type and\nstill sorts its own output, so the `Debug` representation is unchanged.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Make catalog ID iteration deterministic across process runs (clo…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T14:02:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7f1df812544eadf0f48551d0b98abfba3a438e77",
          "body": "…e #906) (#925)\n\nThe doc comment read only \"Alternative to\" with a TODO placeholder. Describe\nthat `LookaheadReplacer` is an alternative to `regex::Replacer` that can inspect\nthe text following a match and reject it via `SkipAheadAndRetry`, modeling the\nlook-ahead pattern that `regex::Replacer` cannot express.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: Complete the truncated doc comment on `LookaheadReplacer` (clos…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T13:34:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8eef1e68450f576f513f568f1a1a33d8daf724ff",
          "body": "…K branch (close #908) (#928)\n\nThe invalid-macro-syntax `else` branch in `InlineLinkReplacer` carried a\nFIXME noting that a `link:` prefix should never reach it: the shared\nNON-ANGLE branch of `INLINE_LINK` let `link:` prefix a bare (bracket-less)\nURL, which then matched and was rejected as invalid \n[…]\nsyntax path.\n\n`NormalizedCaps` gains a third branch mapping and `bare` becomes optional\n(the LINK-MACRO branch always has a trailing attrlist).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: Give the `link:` prefix its own bracket-required INLINE_LIN…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T13:32:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "024721f9252180c4962152effea6365cc966c97d",
          "body": "Settles several pre-1.0 public-API commitments flagged in the adversarial\nreview, each of which would become a breaking change to fix after the freeze:\n\n- Rename the misspelled trait method\n  `InlineSubstitutionRenderer::render_quoted_substitition` to\n  `render_quoted_substitution`.\n- Remove the pro\n[…]\n type and\n`LinkRenderParams::type_` field are removed; and `LinkRenderParams::window`\nchanges from `Option<&'static str>` to `Option<&'a str>`.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor!: Polish public rendering API ahead of 1.0 (close #897) (#929)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T13:30:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "91abb32cc09f6a331ac1c2898655248cb54037be",
          "body": "…ion (close #889) (#920)\n\nAdd a prominent \"Security: rendering untrusted input\" section to the\nREADME (which is also the crate-level doc via `include_str!`), stating\nthat the HTML renderer is not a sanitizer, that attribute-reference\nsubstitution and passthroughs emit raw HTML by design, and that\nco\n[…]\noc must run the output\nthrough an HTML sanitizer such as `ammonia`. Clarify that safe mode\ngoverns file/environment reach, not output escaping.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: Document that untrusted AsciiDoc output requires HTML sanitizat…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T05:14:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "870609273fe4653c8dd8ecea622099c3543654ff",
          "body": "…05) (#924)\n\n* perf: Reduce allocations in the inline substitution pipeline (close #905)\n\nResidual allocation-reduction items from the adversarial review; each is\nsmall and mechanical, and the many-small-blocks-of-plain-prose throughput\ncase benefits from all of them.\n\n- `apply_special_characters` n\n[…]\nng both the\n  no-op-filter borrow branch and the changed-text owned branch.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Reduce allocations in the inline substitution pipeline (close #9…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T05:14:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e053106f32bb6358554dfd2f3fc584574ff3e393",
          "body": "…ounds slice (close #902) (#923)\n\n* fix: Fall back to an empty span instead of the whole span on out-of-bounds slice (close #902)\n\n`Span::slice` / `slice_from` / `slice_to` guarded their bounds only with a\n`debug_assert!`. In a release build, when `.get(range)` returned `None`, the\n`map_or(*self, …)\n[…]\nes;\nthe release fallback behavior is already covered by the `empty()` test.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Fall back to an empty span instead of the whole span on out-of-b…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T05:13:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6ad42b74d3ae456eeccab4f1f7a6dc8504208804",
          "body": "…ciiDoc table cells (close #904) (#922)\n\nFor every AsciiDoc-style (`a`) table cell, `process_content` rebuilt the\nattribute-lock set from scratch, allocating an owned `String` for each of the\n~74 built-in attributes it locked and deep-cloning the whole `HashSet<String>`\nper cell. This was the domina\n[…]\ncall out of the modifiable-attributes loop so the\nper-parser attribute map is made-mut once per cell rather than re-checked on\nevery iteration.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf: Avoid per-cell String allocations when locking attributes in As…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T05:07:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "24ec6d181229f6d09f8dccdcf646fbd5ef918cad",
          "body": "…or (close #907) (#921)\n\nThe `// TODO:` in `section_to_node` described how the section title heading is\nadded in the `Block::Section` match arm (using `section.level()` for the heading\nlevel and `section.section_title()` for the text). That behavior is already fully\nimplemented there, so the note tr\n[…]\nfold its one useful detail (the title heading, like the id,\nlands on the heading rather than the wrapper `<div>`) into the surrounding\ncomment.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: Remove stale TODO restating implemented section-heading behavi…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T05:07:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "80825d50579108831d9bc1f96f5a6e9e43d86cdd",
          "body": "…idelity (#917)\n\n* feat: Map preprocessed spans back to origin file, line, column, and fidelity (close #891)\n\nSpans carry coordinates relative to the single preprocessed buffer, and the\nonly way back to an origin was `SourceMap::original_file_and_line`, which is\nline-only and cannot say whether a li\n[…]\nhe included file's identity is\nnot carried forward into the parent's lines.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Map preprocessed spans back to origin file, line, column, and f…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T04:47:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e64f4ade1fff3da5fba49aebf0aba8c2fb15d6dd",
          "body": "…k macro (close #888) (#911)\n\n* fix: Escape href/target/icon attributes and reject script URIs in link macro (close #888)\n\nSeveral `href`/`target` and icon attribute values were emitted into the\nrendered HTML without escaping the `\"` delimiter, allowing an author to\nbreak out of the attribute and in\n[…]\nnd `render_icon_or_image` (which drops the\nlive link) share one definition.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Escape href/target/icon attributes and reject script URIs in lin…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T01:59:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0c93961c8288c853f6300d9487cb0139a3afe9b2",
          "body": "A UTF-8 byte-order mark (`EF BB BF` = U+FEFF) at the start of the input\nwas not stripped. `preprocess` short-circuits and returns the source\nunchanged when there are no directives, so the U+FEFF became the first\ncharacter of the first line. `Header::parse` requires the line to start\nwith `= `, so a \n[…]\n This matches Asciidoctor, which strips a UTF-8 BOM even\nfor UTF-8 input, and is independent of UTF-16 transcoding, which remains\nout of scope.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Strip a leading UTF-8 BOM before parsing (close #900) (#918)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T01:45:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "436d8144f64c066572d62d4581da228bf52601ec",
          "body": "…nput (close #885) (#910)\n\n* fix: Cap block nesting depth to prevent stack overflow on untrusted input (close #885)\n\nBlock parsing descends recursively through `parse_blocks_until` (delimited\nblock bodies, section bodies, table cells, quote/blockquote content) and\nthrough `ListBlock::parse_inside_li\n[…]\ntores parity with\nthe pre-#885 baseline (measured within run-to-run noise).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Cap block nesting depth to prevent stack overflow on untrusted i…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T01:30:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9c91f6f9c6f3916cb55ae67e3fbfeccfb3bfa644",
          "body": "…r (close #893) (#909)\n\n* fix: Reset document attribute values between parses on a reused Parser (close #893)\n\n`Parser::parse_deferred` reset the catalog, callouts, substitution\nwarnings, section numbering, pending block title, and counters between\nparses but not `attribute_values`, so document-head\n[…]\nic's prose dash convention in the doc comment added by the\nprevious commit.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Reset document attribute values between parses on a reused Parse…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T01:08:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c8aa0e203b0f9a0374a288eab5fcd69524e2134d",
          "body": "…ad (close #887) (#912)\n\n* fix: Honor char boundary when skipping constrained-monospace look-ahead (close #887)\n\nThe constrained-monospace quote regex's leading boundary group\n`[^\\w&;:\"'`}]` matches any non-word Unicode scalar, including multi-byte\ncharacters. When a failed look-ahead skipped the le\n[…]\nage gap left by\nthe multi-byte fix. The escaped text is preserved verbatim.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Honor char boundary when skipping constrained-monospace look-ahe…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T00:40:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "50f578e127fe1a0c76989d01cbf6a21aa8b9a28c",
          "body": "Apply the documented comment/doc style conventions to hand-written\ncomments and documentation text (excluding the vendored `ref/` tree and\nthe tests that quote it):\n\n- Convert prose em dashes to spaced en dashes (366 lines). The one\n  literal em-dash character reference in `virtual_dom.rs` is preser\n[…]\nn test it marks.\n- File tracking issues for an incomplete doc comment and two unlinked\n  TODO/FIXME comments, and link them (#906, #907, #908).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "doc: Normalize comment and doc prose style across the codebase (#915)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T00:37:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a43b990ea8278c9b81394ffd2bff232a57b17a60",
          "body": "…#886) (#914)\n\n* fix: Avoid O(n²) parse time on many repeated block delimiters (close #886)\n\n`QuoteBlock::parse` runs before `CompoundDelimitedBlock` in block dispatch,\nso it is tried for every delimiter line. Its quoted-paragraph path called\n`read_paragraph` (a scan to the next blank line) before t\n[…]\nlines between\nthem) — the shape that previously triggered O(n²) parse time.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Avoid O(n²) parse time on many repeated block delimiters (close …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T00:35:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b5252cb2a4b00dd2dd93049da95c2c90d2178eb9",
          "body": "…ction (close #890) (#913)\n\nThe `Safe` and `Server` docstrings described protections the parser does\nnot actually enforce:\n\n- `Safe` claimed it prevents access to files outside the source file's\n  parent directory. This crate performs no filesystem I/O and does not\n  port Ruby Asciidoctor's `PathRes\n[…]\nent handler's responsibility —\nand that only `Secure`, not `Server`, disables include/asset embedding.\n\nDocumentation only; no behavior change.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: Correct SafeMode Safe/Server docstrings to match enforced prote…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-24T00:28:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "006b8752176d0637c7f3c2535ecbb02f5ba47798",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.25.0 (#879)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T15:21:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cfae1bd47ba42ecab7e0585b59f9f80fa7a40c81",
          "body": null,
          "is_bot": false,
          "headline": "chore: Update README to reflect fully feature-complete status (#884)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T15:15:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b2106856ea6c1c62dcd52c1021720ca2d7b5d294",
          "body": "…(close #871) (#883)\n\n* test: Verify link attrlist enclosure rule for invalid attribute names (close #871)\n\nPromote the \"enclosure only required when the text preceding the equals\nsign matches a valid attribute name\" sentence in the link/URL macro\nattribute-parsing spec from a non-normative note to \n[…]\nor future spec-coverage work and silence the\nunused-macro/-import warnings.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Verify link attrlist enclosure rule for invalid attribute names …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T15:04:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "48407cc93dcdb2524698690360334ec80e85f99e",
          "body": "… content (close #877) (#881)\n\n`reindent_included_lines` previously returned included content unchanged\nwhenever the `indent` attribute was absent, so `tabsize`-driven tab\nexpansion only fired when `indent` was also supplied.\n\nPer the spec, when `tabsize` is set, tabs are replaced with spaces\nregard\n[…]\nxpansion now runs\nwhenever `tabsize` is positive; indentation normalization is applied\nindependently when `indent` is present and non-negative.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Expand tabs from `tabsize` independently of `indent` on included…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:53:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1c10c0badc6182a1de62af87f02a150e2f994d42",
          "body": "…ing blank lines (close #876) (#882)\n\nPromote the `to_do_verifies!` block in `document_test.rs` to two real\n`verifies!` tests, backed by an `InlineFileHandler` fixture reproducing\nAsciidoctor's canonical `include-with-leading-blank-line.adoc` (two blank\nlines before the level-0 title).\n\n- A whole-fi\n[…]\ne and sets `:toc:`.\n- `lines=6` selects by original line number, skipping the leading blank\n  lines and the title so only the section survives.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: Verify document-title & lines= selection for includes with lead…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:53:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "de9a4cff700cb105ba39c66753cc902e78bfc5a7",
          "body": "…lose #801) (#880)\n\n`WarningType` became part of the public API in #799, so its variant names\nand `Display` strings now need to read as a deliberate, consistent set. This\nis the one-time review the long-standing TODO above `InvalidMacroName` asked\nfor.\n\nVariant renames (breaking for anyone matching \n[…]\ner\"). Wording is otherwise unchanged. This changes user-visible\nwarning text.\n\nThe `TODO (#801)` marker is removed now that the review is done.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(warnings)!: Review WarningType variant names and messages (c…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:44:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0c6a48c7687d434f46b001a991b9aaae7ca4f778",
          "body": "…878)\n\nConvert the now-testable table structural-container row to verifies! and\nreclassify the permanently-unverifiable / out-of-scope blocks as\nnon_normative! with justifications:\n\n- delimited.rs: the four table delimiters (`|===`, `,===`, `:===`, `!===`)\n  now assert the `table` context and conten\n[…]\ne two genuinely-deferred blocks now cite tracking issues #876 (include\ndoctitle recognition / lines= selection) and #877 (block-level tabsize).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: Resolve remaining to_do_verifies! blocks from the #628 sweep (#…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:39:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2f37e9dd217d6c7595c77300828d290df3b15aaa",
          "body": "…) (#874)\n\n* test: Cover description-list delimiter and anchor rules (close #864)\n\nThe opening `non_normative!` block in `lists/description.rs` reproduced\nseveral normative parsing rules for description lists but none were\nexercised by a test. Split the block so the normative prose is now backed\nby \n[…]\ntrast to\na leading `[[id]]` anchor which becomes part of the rendered term.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": " chore: Cover description-list delimiter and anchor rules (close #864…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:37:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3e721feddf89a868c943c97bf3abb78d0b32387a",
          "body": "…horthand ID/role order, AsciiDoc-cell directive) (#873)\n\n* test: Cover `title`-attribute fallback for the document title\n\nSplit the `[#title-attr]` `non_normative!` block so the normative\nfallback rule is verified: with no level 0 section title and no\n`doctitle` attribute, a `title` attribute entry\n[…]\name\ndirective on the following line acts as a normal multiline conditional.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: Close mislabeled-normative coverage gaps (doctitle fallback, s…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:27:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "18685312ef868d1f9906882096a40a25a8224b63",
          "body": "…se #865) (#875)\n\nSeveral inline-macro spec pages wrapped a normative parsing rule in\n`non_normative!` without covering tests. Add `verifies!` coverage for\neach rule the parser already implements correctly, and a justified\n`to_do_verifies!` marker for the one it does not:\n\n- Inline image alt-text: a\n[…]\next before `=` is a valid attribute name. The parser does not yet\n  honor this; the marker documents current behavior and is tracked by\n  #871.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: Cover inline-macro spec rules hidden behind non_normative! (clo…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:26:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9aad9fafcabf48bfd30a115b4693f86279bde551",
          "body": "…combinators (close #866) (#868)\n\n* test: Cover mixed ifdef/ifndef combinator behavior (close #866)\n\nThe `non_normative!` block in `ifdef_ifndef.rs` stated the normative rule\nthat the `,` (or) and `+` (and) combinators cannot be combined in a single\nconditional-directive expression, but no test asse\n[…]\naffected. Extend `combinators_cannot_be_mixed` to cover the `+`-first case.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Match Asciidoctor's first-delimiter rule for mixed ifdef/ifndef …",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:14:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5051db0ceb815d7961afb2c5fc2d53131d6ee2df",
          "body": "Port Asciidoctor's `doc.register :links, target` so the parser records\nevery link target it encounters, exposed as `Catalog::links()`. Like the\nimage registry, population is gated on the `catalog_assets` option and\nrecorded in substitution-pass order.\n\nAll four Asciidoctor registration sites are covered: bare-URL autolink,\n`link:` macro, `mailto:`/link macro, and email autolink (the last of\nwhich the original TO DO markers had missed).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Populate the document catalog's link registry (close #335) (#872)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:10:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e06f0caf0984685dcb64fa452c10e6ca152a60d2",
          "body": "Audit of commented-out code turned up two genuinely dead blocks in the\ncrate's own source (excluding quoted Asciidoctor / AsciiDoc reference\nmaterial):\n\n- `passthroughs.rs`: an abandoned trailing-backslash truncation approach,\n  superseded by the retry logic that follows it.\n- `sdd/src/main.rs`: a developer debugging shortcut that scoped file\n  processing to a single file.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: Remove commented-out dead code (close #705) (#870)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T14:09:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "dbacb2413f412cdbee15fd2ebd8ff150b1c77b34",
          "body": null,
          "is_bot": false,
          "headline": "chore(asciidoc-parser): release v0.24.0 (#863)",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T04:33:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "99cf75ffb9858f73cb164da754ce25058e314f13",
          "body": "…tle (#862)\n\nAdd a regression test asserting that a block attribute line above the\ndocument title whose value carries a `{counter:…}` reference does not fire\nthe counter at header time when the run is ultimately rejected (here by an\nembedded `[[anchor]]`).\n\n`document_title_follows_block_metadata` sc\n[…]\nparser and the counter advances exactly once. This\nlocks in that behavior, salvaging the one piece of unique coverage from the\nsuperseded #833.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: Cover counter deferral for a rejected metadata run above the ti…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T04:27:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0944b66c0ba58ae3c2a2dc942f070698241756d1",
          "body": "…ub (#861)\n\nIssue #308 asked whether a block title can span multiple lines via a\ntrailing `+`. The answer is no: a title is a single line, and a trailing\n` +` is retained literally rather than joined to the following line\n(confirmed against the parser). Replace the stale `TO DO` comment linking\nto #\n[…]\n `to_do_verifies!` stub convention.\n\nThe `|Titles |{y}` spec-coverage marker stays; that gap is tracked by the\n`to_do_verifies!` sweep in #628.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: Remove resolved #308 reference from post_replacements titles st…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T04:07:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "adf9ff733355bea5b2dba6b52c30deb736ecbc0d",
          "body": "…9) (#852)\n\n* fix: Fuse legacy `+`-continued multi-line attribute values (close #729)\n\nAn attribute entry value can be continued across lines with a trailing\n` +` (legacy) as well as ` \\` (modern). Previously only the backslash\ncontinuation was fused; a legacy `+`-continued value was not joined — th\n[…]\nn the document body).\n\nAdds span-, fold-, and parse-level regression tests.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Fuse legacy `+`-continued multi-line attribute values (close #72…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T04:06:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3f2e0d78c748fff27314a181285a2863f43d4b05",
          "body": "…732) (#850)\n\n* fix: Formal `role=` replaces roles set via shorthand `.role` (close #732)\n\nWhen merging multiple block attribute lines, roles now follow\nAsciidoctor's running model: a formal `role=` entry replaces every role\naccumulated so far, while shorthand `.role` entries append. Previously\nall \n[…]\nat\n  the formal value replaces the running roles and the shorthand appends.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: Formal `role=` replaces roles set via shorthand `.role` (close #…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T03:59:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cab8554693ddb8d05d68eb5dd37bdf05384d37ff",
          "body": "…lose #745) (#848)\n\n* feat: Drop YAML/TOML front matter when `skip-front-matter` is set (close #745)\n\nA `---`-fenced block at the very top of the document is now removed – and\nits content captured in the `front-matter` document attribute – when the\n`skip-front-matter` attribute is set, mirroring Asc\n[…]\n, `+++` TOML is not, and the content is\nstored verbatim rather than parsed.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Drop YAML-style front matter when `skip-front-matter` is set (c…",
          "author_name": "Eric Scouten",
          "author_login": "scouten",
          "committed_at": "2026-07-23T03:54:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 55,
      "commits_last_year": 546,
      "latest_release_at": "2026-08-01T16:14:24Z",
      "latest_release_tag": "v0.29.4",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 37,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 0.7
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "sdd",
          "exists": true,
          "license": "Apache-2.0",
          "keywords": [
            "concurrent",
            "garbage",
            "memory",
            "epoch",
            "lock-free",
            "data-structures",
            "concurrency",
            "memory-management"
          ],
          "ecosystem": "crates",
          "matches_repo": false,
          "registry_url": "https://crates.io/crates/sdd",
          "is_deprecated": false,
          "latest_version": "4.8.8",
          "repository_url": "https://codeberg.org/wvwwvwwv/scalable-delayed-dealloc",
          "versions_count": 72,
          "total_downloads": 77608068,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 5899173,
          "first_published_at": "2024-04-14T18:03:40.616625Z",
          "latest_published_at": "2026-07-02T14:12:15.625601Z",
          "latest_version_yanked": false,
          "days_since_latest_publish": 30
        },
        {
          "name": "asciidoc-parser",
          "exists": true,
          "license": "MIT OR Apache-2.0",
          "keywords": [
            "parser",
            "asciidoc",
            "parser-implementations"
          ],
          "ecosystem": "crates",
          "matches_repo": true,
          "registry_url": "https://crates.io/crates/asciidoc-parser",
          "is_deprecated": false,
          "latest_version": "0.29.4",
          "repository_url": "https://github.com/asciidoc-rs/asciidoc-parser",
          "versions_count": 55,
          "total_downloads": 13542,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 2012,
          "first_published_at": "2024-10-26T22:27:57.063155Z",
          "latest_published_at": "2026-08-01T16:14:20.394752Z",
          "latest_version_yanked": false,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 4,
      "stars": 34,
      "watchers": 2,
      "fork_history": {
        "days": [
          {
            "date": "2026-01-23",
            "count": 1
          },
          {
            "date": "2026-02-17",
            "count": 1
          },
          {
            "date": "2026-04-01",
            "count": 1
          },
          {
            "date": "2026-07-18",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 4,
        "total_forks": 4
      },
      "star_history": null,
      "open_issues_and_prs": 5
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": true,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "Cargo.toml",
        "parser/Cargo.toml",
        "sdd/Cargo.toml"
      ],
      "largest_source_bytes": 434972,
      "source_files_sampled": 419,
      "oversized_source_files": 45,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "Cargo.toml",
        "parser/Cargo.toml",
        "sdd/Cargo.toml"
      ],
      "advisories": {
        "error": "No resolved dependencies carried a version and a supported ecosystem",
        "scope": "repository_graph",
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 10,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "crates"
      ],
      "dependencies": [
        {
          "name": "bytecount",
          "manifest": "parser/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.6.7"
        },
        {
          "name": "memchr",
          "manifest": "parser/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2.6.4"
        },
        {
          "name": "percent-encoding",
          "manifest": "parser/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2.3.2"
        },
        {
          "name": "regex",
          "manifest": "parser/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.11.1"
        },
        {
          "name": "self_cell",
          "manifest": "parser/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1.2.0"
        },
        {
          "name": "thiserror",
          "manifest": "parser/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2.0.1"
        },
        {
          "name": "walkdir",
          "manifest": "sdd/Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "2.5"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "bytecount",
            "direct": true,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "memchr",
            "direct": true,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "percent-encoding",
            "direct": true,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "regex",
            "direct": true,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "self_cell",
            "direct": true,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "thiserror",
            "direct": true,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "walkdir",
            "direct": true,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "codspeed-criterion-compat",
            "direct": false,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "criterion",
            "direct": false,
            "version": null,
            "ecosystem": "crates"
          },
          {
            "name": "pretty_assertions_sorted",
            "direct": false,
            "version": null,
            "ecosystem": "crates"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 10,
        "direct_count": 7,
        "indirect_count": 3
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 772,
        "open_issues": 3,
        "closed_ratio": 0.987,
        "closed_issues": 223,
        "closed_unmerged_prs": 40
      },
      "bus_factor": 2,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "scouten",
          "commits": 759,
          "avatar_url": "https://avatars.githubusercontent.com/u/158391?v=4"
        },
        {
          "type": "User",
          "login": "mojavelinux",
          "commits": 723,
          "avatar_url": "https://avatars.githubusercontent.com/u/79351?v=4"
        },
        {
          "type": "User",
          "login": "graphitefriction",
          "commits": 37,
          "avatar_url": "https://avatars.githubusercontent.com/u/1124042?v=4"
        },
        {
          "type": "User",
          "login": "ggrossetie",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/333276?v=4"
        },
        {
          "type": "User",
          "login": "larryv",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/281175?v=4"
        },
        {
          "type": "User",
          "login": "mmattel",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/3321281?v=4"
        },
        {
          "type": "User",
          "login": "ahus1",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/3957921?v=4"
        },
        {
          "type": "User",
          "login": "btat",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/1832069?v=4"
        },
        {
          "type": "User",
          "login": "Vampire",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/325196?v=4"
        },
        {
          "type": "User",
          "login": "danyill",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/674783?v=4"
        }
      ],
      "contributors_sampled": 22,
      "top_contributor_share": 0.492
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "pr_title.yml",
        "release.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 3,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 1/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 14 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 30 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": 10,
            "reason": "all dependencies are pinned",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "85320d8042ad10832b6e6cdc5cc7f7ef740c558f",
        "ran_at": "2026-08-01T18:21:44Z",
        "aggregate_score": 6.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-08-01T17:56:39Z",
      "oldest_open_prs": [
        {
          "number": 1039,
          "created_at": "2026-08-01T17:54:25Z",
          "last_comment_at": "2026-08-01T17:57:42Z",
          "last_comment_author": "codspeed-hq"
        },
        {
          "number": 1040,
          "created_at": "2026-08-01T18:13:36Z",
          "last_comment_at": "2026-08-01T18:16:29Z",
          "last_comment_author": "codspeed-hq"
        }
      ],
      "last_merged_pr_at": "2026-08-01T17:53:45Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 943,
          "created_at": "2026-07-24T22:37:22Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 944,
          "created_at": "2026-07-24T22:37:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 1036,
          "created_at": "2026-08-01T17:29:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/asciidoc-rs/asciidoc-parser",
    "host": "github.com",
    "name": "asciidoc-parser",
    "owner": "asciidoc-rs"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": "The weighted overall 66 is calibrated to 77 on the published index scale (record calibration 2026-08-02).",
      "notes": [
        {
          "code": "overall_calibration",
          "params": {
            "raw": 66,
            "calibrated": 77,
            "calibration": "2026-08-02"
          }
        }
      ],
      "value": 77,
      "inputs": {
        "security": 61,
        "vitality": 94,
        "community": 43,
        "governance": 66,
        "calibration": "2026-08-02",
        "engineering": 61,
        "ai_readiness": 64,
        "weighted_overall_raw": 66
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "exceptional",
        "name": "Vitality",
        "value": 94,
        "weight": 0.21,
        "metrics": [
          {
            "key": "development_activity",
            "band": "excellent",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "commits_last_year": 546,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 37
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "37/52 weeks with commits",
                "points": 25.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 37
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "546 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 546
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "exceptional",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 55,
              "latest_release_tag": "v0.29.4",
              "releases_from_tags": false,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 0.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "55 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 55
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.7
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "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": 3,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 3 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 3
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "weak",
        "name": "Community & Adoption",
        "value": 43,
        "weight": 0.17,
        "metrics": [
          {
            "key": "popularity",
            "band": "at_risk",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 29,
            "inputs": {
              "forks": 4,
              "stars": 34,
              "watchers": 2,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "34 stars",
                "points": 24.6,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 34
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "4 forks",
                "points": 4,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "2 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "readme_badges": null,
              "has_contributing": false,
              "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": "recognized license (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "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": 55,
            "inputs": {
              "packages": [
                "asciidoc-parser"
              ],
              "dependents": null,
              "ecosystems": "crates",
              "total_downloads": 13542,
              "monthly_downloads": 2012
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,012 downloads/month across crates",
                "points": 44.1,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2012,
                      "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": "good",
        "name": "Sustainability & Governance",
        "value": 66,
        "weight": 0.23,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "moderate",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "bus_factor": 2,
              "contributors_sampled": 22,
              "top_contributor_share": 0.492
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "2 contributor(s) cover half of all commits",
                "points": 25.2,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 49% of commits",
                "points": 11.4,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 49
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "22 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 22
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 14 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "excellent",
            "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": 80,
            "inputs": {
              "merged_prs": 772,
              "open_issues": 3,
              "closed_issues": 223,
              "prs_merged_7d": null,
              "prs_decided_7d": null,
              "prs_merged_30d": null,
              "prs_decided_30d": null,
              "issue_closed_ratio": 0.987,
              "closed_unmerged_prs": 40,
              "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": "99% of issues closed",
                "points": 41.5,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 99
                    }
                  }
                ],
                "max_points": 42
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "772/812 decided PRs merged",
                "points": 28.5,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 772,
                      "decided": 812
                    }
                  }
                ],
                "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/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 34,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "asciidoc-rs",
              "public_repos": 2,
              "account_age_days": 175
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "0 followers of asciidoc-rs",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "asciidoc-rs"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "2 public repos, account ~0 yr old",
                "points": 4.4,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 2
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "exceptional",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "asciidoc-parser"
              ],
              "ecosystems": "crates",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on crates",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "crates"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "55 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 55
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 61,
        "weight": 0.19,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "3 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "topics": [
                "asciidoc",
                "markup",
                "parser"
              ],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "3 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "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": 61,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 61,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 6.1
            },
            "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": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 1/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 14 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 30 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": "all dependencies are pinned",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "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": 21
            },
            "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": 64,
        "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": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "excellent",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 81,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": true,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.86,
              "toolchain_manifests": [
                "Cargo.toml",
                "parser/Cargo.toml",
                "sdd/Cargo.toml"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Cargo.toml, parser/Cargo.toml, sdd/Cargo.toml (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "Cargo.toml, parser/Cargo.toml, sdd/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": "devcontainer",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "devcontainer"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "86 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 86,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "dependency automation configured, none observed in the sampled commits",
                "points": 5,
                "status": "partial",
                "details": [
                  {
                    "code": "dependency_bot_config_only",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "all dependencies are pinned",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "exceptional",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 94,
            "inputs": {
              "primary_language": "Rust",
              "largest_source_bytes": 434972,
              "source_files_sampled": 419,
              "oversized_source_files": 45
            },
            "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": "45/419 source files over 60KB",
                "points": 49.1,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 419,
                      "oversized": 45
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "weak",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? 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"
      ],
      "labels": [
        "library"
      ],
      "scores": {
        "library": 6
      },
      "primary": "library",
      "evidence": [
        {
          "tier": "distribution",
          "label": "library",
          "source": "registry:crates",
          "weight": 6
        }
      ],
      "artifacts": [],
      "confidence": "medium",
      "host_extension": false,
      "runs_as_process": false,
      "consumed_by_code": true
    },
    "metrics_version": "2.5.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "crates package 'sdd' points at a different repository (https://codeberg.org/wvwwvwwv/scalable-delayed-dealloc); excluded from ecosystem scoring",
    "deps.dev does not index crates:asciidoc-parser@0.29.4; advisories assessed against the repository dependency graph instead",
    "No resolved dependencies carried a version and a supported ecosystem"
  ],
  "report_type": "repository",
  "generated_at": "2026-08-01T18:22:10.907697Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/asciidoc-rs/asciidoc-parser.svg",
  "full_name": "asciidoc-rs/asciidoc-parser",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

Bewertungen sind Signale, keine Garantien. Sie spiegeln öffentlich sichtbare Praxis auf GitHub wider — kein Code-Audit und keine Sicherheitsgarantie.

Fehlende Daten werden ausgeschlossen und die Gewichte neu normiert, nie als null bewertet. Die Methodik ist versioniert und offen: Metriken v2.5.0, Schema v0.27.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte Statistikencrates.io.