From 7967b3125c8191d7315d1b402cec356c5bc1654b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Ahlert?= Date: Sat, 2 May 2026 02:23:27 -0300 Subject: [PATCH] docs: enable markdownlint MD040 and tag all fenced code blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #18. Flips MD040 from `false` to `true` and tags the 64 previously untagged fences across the tree. Most fences ended up `text` (MCP call sketches, URL examples, dir trees, plain output, commit trailers). 3 got `html` for HTML-comment idempotency markers and the
envelope, 3 `markdown` for the AI-disclosure block and rollup body samples, 1 `yaml` for the subagent return block in sync-security-issue. One nested-fence case in allocate-cve/SKILL.md needed the outer fence promoted from 3 to 4 backticks so the inner 3-backtick block renders as an actual nested code block instead of breaking the outer one. Signed-off-by: André Ahlert --- .claude/skills/allocate-cve/SKILL.md | 6 ++--- .claude/skills/fix-security-issue/SKILL.md | 2 +- .../import-security-issue-from-md/SKILL.md | 12 +++++----- .../import-security-issue-from-pr/SKILL.md | 6 ++--- .claude/skills/import-security-issue/SKILL.md | 6 ++--- .../skills/invalidate-security-issue/SKILL.md | 6 ++--- .claude/skills/sync-security-issue/SKILL.md | 14 +++++------ .markdownlint.json | 8 +++---- AGENTS.md | 12 +++++----- CONTRIBUTING.md | 2 +- projects/_template/fix-workflow.md | 2 +- secure-agent-setup.md | 4 ++-- tools/github/status-rollup.md | 6 ++--- tools/gmail/draft-backends.md | 2 +- tools/gmail/operations.md | 10 ++++---- tools/gmail/ponymail-archive.md | 10 ++++---- tools/ponymail/operations.md | 24 +++++++++---------- tools/ponymail/tool.md | 6 ++--- tools/vulnogram/allocation.md | 2 +- 19 files changed, 70 insertions(+), 70 deletions(-) diff --git a/.claude/skills/allocate-cve/SKILL.md b/.claude/skills/allocate-cve/SKILL.md index b4b4c490..7d0f453d 100644 --- a/.claude/skills/allocate-cve/SKILL.md +++ b/.claude/skills/allocate-cve/SKILL.md @@ -263,14 +263,14 @@ over-stripping is worse than leaving one redundant word in. Compose a proposal block that carries everything the user needs in one copy-paste pass: -```markdown +````markdown **Allocate a CVE for [#](https://github.com//issues/).** 1. Open the ASF Vulnogram allocation form: 2. In the *Title* field, paste this: - ``` + ```text ``` @@ -284,7 +284,7 @@ one copy-paste pass: 4. Click *Allocate*. Vulnogram returns a `CVE-YYYY-NNNNN` ID. 5. Paste the allocated CVE ID back into this conversation — the skill will pick it up and update the tracker automatically. -``` +```` Scope → Vulnogram product table: the adopting project's scope labels and their CVE product / package-name mappings are defined in diff --git a/.claude/skills/fix-security-issue/SKILL.md b/.claude/skills/fix-security-issue/SKILL.md index 63f7291b..a9fcdfdd 100644 --- a/.claude/skills/fix-security-issue/SKILL.md +++ b/.claude/skills/fix-security-issue/SKILL.md @@ -420,7 +420,7 @@ Write out the exact `--body` the skill will pass to - the standard Gen-AI disclosure block per [`/contributing-docs/05_pull_requests.rst`](https://github.com//blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions): - ``` + ```markdown ##### Was generative AI tooling used to co-author this PR? - [X] Yes — Claude Opus 4.6 (1M context) diff --git a/.claude/skills/import-security-issue-from-md/SKILL.md b/.claude/skills/import-security-issue-from-md/SKILL.md index afb4ac32..014e4322 100644 --- a/.claude/skills/import-security-issue-from-md/SKILL.md +++ b/.claude/skills/import-security-issue-from-md/SKILL.md @@ -244,7 +244,7 @@ The tracker title is the finding's `# Title` with the standard convention; see [`tools/github/issue-template.md`](../../../tools/github/issue-template.md)): -``` +```text [ Security Report ] ``` @@ -335,7 +335,7 @@ exactly one blank line before `
`. Render a single proposal covering every parsed finding: -``` +```text — N findings parsed. | # | Severity | Category | Title | Possible duplicate | @@ -539,7 +539,7 @@ purpose for this finding and would otherwise accumulate. After every finding lands, print a short one-liner so the user can see progress on long batches: -``` +```text [K/N] #NNN — ``` @@ -619,7 +619,7 @@ the validity discussion produces signal. ### Example 1 — A six-finding AI-scan output -``` +```text import findings from /tmp/scan-michaelwinser-airflow-2026-04-28.md ``` @@ -633,7 +633,7 @@ reference. ### Example 2 — A single-finding scanner export -``` +```text import findings from ~/Downloads/sast-export.md ``` @@ -644,7 +644,7 @@ as a Gmail import; the only difference is the source format. ### Example 3 — Malformed input -``` +```text import findings from /tmp/notes.md ``` diff --git a/.claude/skills/import-security-issue-from-pr/SKILL.md b/.claude/skills/import-security-issue-from-pr/SKILL.md index 154f5ce2..337b09c3 100644 --- a/.claude/skills/import-security-issue-from-pr/SKILL.md +++ b/.claude/skills/import-security-issue-from-pr/SKILL.md @@ -668,7 +668,7 @@ with other trackers. ### Example 1 — `providers` scope, already merged -``` +```text import from pr 65703 ``` @@ -687,7 +687,7 @@ disclosure; see *[Reporter credit policy](#reporter-credit-policy-for-public-pr- ### Example 2 — `airflow` scope, in-flight -``` +```text import from pr https://github.com//pull/65999 ``` @@ -700,7 +700,7 @@ proposes everything; on user confirmation, the tracker lands ### Example 3 — Mixed-scope PR (blocker) -``` +```text import from pr 66042 ``` diff --git a/.claude/skills/import-security-issue/SKILL.md b/.claude/skills/import-security-issue/SKILL.md index 94b8d7ef..7d127eed 100644 --- a/.claude/skills/import-security-issue/SKILL.md +++ b/.claude/skills/import-security-issue/SKILL.md @@ -208,7 +208,7 @@ When PonyMail MCP is enabled and authenticated (Step 0) **and** `tools.ponymail.private_lists`, run the archive as a **paired authoritative check** against the Gmail result set: -``` +```text mcp__ponymail__search_list( list: "security", domain: ".apache.org", @@ -439,7 +439,7 @@ fuzzy-match search against existing issues on three orthogonal keys: For every candidate, surface the match results under a *Potential duplicates* sub-item in the Step 5 proposal — format: -``` +```markdown - thread — "" - GHSA match: [#NNN](...) "GHSA-xxxx-yyyy-zzzz" (STRONG) - Code-pointer match: [#MMM](...) "BaseSerialization.deserialize" (MEDIUM) @@ -511,7 +511,7 @@ authenticated (Step 0) **and** `security@.apache.org` is in `config/user.md` → `tools.ponymail.private_lists`, **PonyMail MCP is the primary backend for this step**: -``` +```text mcp__ponymail__search_list( list: "security", domain: ".apache.org", diff --git a/.claude/skills/invalidate-security-issue/SKILL.md b/.claude/skills/invalidate-security-issue/SKILL.md index 598b81ee..06b78eb7 100644 --- a/.claude/skills/invalidate-security-issue/SKILL.md +++ b/.claude/skills/invalidate-security-issue/SKILL.md @@ -616,7 +616,7 @@ Hand-off line: ### Example 1 — `security@`-imported, dag-author-input class -``` +```text invalidate 244 ``` @@ -634,7 +634,7 @@ verbatim quotes and the draft ID. Hand-off: terminal. ### Example 2 — PR-imported, no email -``` +```text invalidate 355 ``` @@ -652,7 +652,7 @@ import-from-pr skill's golden rules. ### Example 3 — Hard stop: CVE already allocated -``` +```text invalidate 257 ``` diff --git a/.claude/skills/sync-security-issue/SKILL.md b/.claude/skills/sync-security-issue/SKILL.md index c8218706..52d13688 100644 --- a/.claude/skills/sync-security-issue/SKILL.md +++ b/.claude/skills/sync-security-issue/SKILL.md @@ -195,7 +195,7 @@ concurrently, which is exactly what the sync needs. Each subagent must return a single code block (or JSON) with exactly these fields so the orchestrator can merge deterministically: -``` +```yaml issue: title: scope_label: airflow | providers | chart | @@ -439,7 +439,7 @@ backend for this step** — the archive is authoritative and reaches back further than any single user's Gmail window. Run the distinctive-phrase search against: -``` +```text mcp__ponymail__search_list( list: "security", domain: ".apache.org", @@ -681,7 +681,7 @@ authenticated (Step 0) **and** `security@.apache.org` is in `config/user.md` → `tools.ponymail.private_lists`, **PonyMail MCP is the primary path** for reviewer-comment archive queries: -``` +```text mcp__ponymail__search_list( list: "security", domain: ".apache.org", @@ -1073,7 +1073,7 @@ will change and *why*. Group them by category: - **PonyMail MCP (preferred when enabled).** If Step 0 recorded `ponymail_authenticated: true`, call: - ``` + ```text mcp__ponymail__search_list( list: "users", domain: ".apache.org", @@ -1455,7 +1455,7 @@ will change and *why*. Group them by category: **Idempotency.** Before proposing, scan the issue's existing comments for the marker - ``` + ```html ``` exactly. If a comment carrying this marker already exists, **do @@ -1537,7 +1537,7 @@ will change and *why*. Group them by category: **Idempotency.** Before proposing, scan the issue's existing comments for the marker - ``` + ```html ``` exactly. If a comment carrying this marker already exists, do not @@ -1624,7 +1624,7 @@ the actual person, in this order: - **PonyMail MCP (preferred when enabled).** `dev@` is a public list; no LDAP allowlist check is needed. Call: - ``` + ```text mcp__ponymail__search_list( list: "dev", domain: "", diff --git a/.markdownlint.json b/.markdownlint.json index a336c7d1..5bc76c30 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -1,5 +1,5 @@ { - "$comment": "Markdownlint config for apache/airflow-steward. The rule set is deliberately minimal — only enables checks that catch real bugs (broken anchors, malformed code spans, malformed link references). Style choices that the existing docs already settled (compact tables, hyphen list markers, ordered-list numbering, fenced-language tagging) are left alone so the consolidation does not balloon the diff.", + "$comment": "Markdownlint config for apache/airflow-steward. The rule set is deliberately minimal — only enables checks that catch real bugs (broken anchors, malformed link references, untagged fenced code). Style choices that the existing docs already settled (compact tables, hyphen list markers, ordered-list numbering) are left alone.", "default": true, @@ -16,7 +16,7 @@ "MD033": false, "MD034": false, "MD036": false, - "MD040": false, + "MD038": false, "MD041": false, "MD046": false, "MD050": false, @@ -24,11 +24,11 @@ "MD059": false, "MD060": false, - "MD038": false, + "MD040": true, "MD051": true, "MD053": true, "$comment-MD038": "MD038 (no space inside code spans) is disabled because the steward docs intentionally use literal markdown-syntax samples like `# ` (H1), `### ` (H3), `- ` (list marker) inside backticks to illustrate markdown rendering. The rule has no per-context allowlist and would force escape-everywhere across many files. Re-enable in a follow-up that escapes those samples consistently.", - "$comment-rationale": "MD051 (link-fragments) catches broken cross-references — exactly the bug class that surfaced 5 real broken anchors on the existing tree. MD053 catches dangling link-reference definitions. Everything else is style and is intentionally off so this PR stays diff-minimal." + "$comment-rationale": "MD040 catches untagged fenced code blocks — surfaces 64 of them in the initial sweep, all tagged in this PR. MD051 (link-fragments) catches broken cross-references — exactly the bug class that surfaced 5 real broken anchors on the previous sweep. MD053 catches dangling link-reference definitions." } diff --git a/AGENTS.md b/AGENTS.md index e3aaaabc..3e6fad93 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -232,7 +232,7 @@ at the root of its tracker repository. The framework refers to this directory via the placeholder ``. Concretely, an adopting project lays out: -``` +```text / └── .apache-steward/ ├── apache-steward/ # (submodule) clone of this framework @@ -371,13 +371,13 @@ if a hook is failing, fix the underlying issue or update the hook configuration itself. **Re-read this rule before preparing every `git commit`.** Use a `Generated-by:` trailer instead. The form is: - ``` + ```text Generated-by: ``` Concrete example for Claude Code: - ``` + ```text Generated-by: Claude Code (Opus 4.7) ``` @@ -859,7 +859,7 @@ not as bare text. The canonical link is the adopting project's CVE-tool record URL, which any security team member can click through to the live CVE record we control: -``` +```text https://cveprocess.apache.org/cve5/ ``` @@ -873,7 +873,7 @@ CVE record is visible on public databases), additionally link to the public `cve.org` / MITRE record so non-security-team readers can see the public description without needing access to the ASF tool: -``` +```text https://www.cve.org/CVERecord?id= ``` @@ -964,7 +964,7 @@ messages, internal notes, `SKILL.md` files — render it as a **clickable markdown link**, not as a bare `#NNN` or `#NNN`. The URL format is: -``` +```text https://github.com//issues/ https://github.com//pull/ https://github.com//issues/#issuecomment- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0931afc..b9081658 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -79,7 +79,7 @@ four — no hard-coded project assumptions anywhere. ### Directory tree -``` +```text . ├── README.md # Canonical 16-step handling process + conventions ├── AGENTS.md # Editorial rules: tone, brevity, confidentiality, diff --git a/projects/_template/fix-workflow.md b/projects/_template/fix-workflow.md index f252fb7c..7edb7411 100644 --- a/projects/_template/fix-workflow.md +++ b/projects/_template/fix-workflow.md @@ -68,7 +68,7 @@ TODO: the project's convention for AI-assisted commits. Example: And the concrete trailer text for this project: -``` +```text Generated-by: TODO: model + URL to the project's Gen-AI disclosure anchor ``` diff --git a/secure-agent-setup.md b/secure-agent-setup.md index a011948d..2642c5a0 100644 --- a/secure-agent-setup.md +++ b/secure-agent-setup.md @@ -311,7 +311,7 @@ the manifest, never installs anything, never opens a PR. The framework's `/schedule` slash-command lets you wire the check script into a recurring agent without leaving Claude Code: -``` +```text /schedule weekly run tools/agent-isolation/check-tool-updates.sh and surface upgrade candidates ``` @@ -742,7 +742,7 @@ already follow this pattern. A minimal repo layout: -``` +```text ~/.claude-config/ # the synced repo's checkout ├── CLAUDE.md # symlinked → ~/.claude/CLAUDE.md ├── scripts/ diff --git a/tools/github/status-rollup.md b/tools/github/status-rollup.md index fc9cf035..9ee8bd01 100644 --- a/tools/github/status-rollup.md +++ b/tools/github/status-rollup.md @@ -193,7 +193,7 @@ let them pick which one to keep. Construct the new body by concatenating the old body + a ruler + the new entry, with exactly one blank line on each side of the ruler: -``` +```text --- @@ -229,7 +229,7 @@ arbitrary comment, and the `--input` flag is needed because Only if Step 1 returned no existing rollup. Prepend the marker line and emit the new entry as the rollup's first entry: -``` +```markdown ``` @@ -292,7 +292,7 @@ For each foldable legacy comment, in chronological order: 1. **Reconstruct the entry shape.** Take the legacy body and wrap it in the rollup's `
` envelope: - ``` + ```html
· @ · diff --git a/tools/gmail/draft-backends.md b/tools/gmail/draft-backends.md index 2923dcb2..245afb47 100644 --- a/tools/gmail/draft-backends.md +++ b/tools/gmail/draft-backends.md @@ -142,7 +142,7 @@ The detection rule depends on which backend created the prior draft: (see the *Known issue* section below). Detect them by reading the thread directly: - ``` + ```text mcp__claude_ai_Gmail__get_thread(threadId: "", messageFormat: MINIMAL) ``` diff --git a/tools/gmail/operations.md b/tools/gmail/operations.md index db2e4790..e5e128cd 100644 --- a/tools/gmail/operations.md +++ b/tools/gmail/operations.md @@ -44,7 +44,7 @@ Every skill that talks to Gmail does a one-call pre-flight in Step 0 to confirm the MCP is reachable and the user's account subscribes to the project's security list: -``` +```text mcp__claude_ai_Gmail__search_threads( query='list:', pageSize=1, @@ -65,7 +65,7 @@ fix the setup rather than guessing. ### Search threads -``` +```text mcp__claude_ai_Gmail__search_threads( query='', pageSize=, @@ -82,7 +82,7 @@ the skills use, see [`search-queries.md`](search-queries.md). ### Get thread -``` +```text mcp__claude_ai_Gmail__get_thread( threadId='', messageFormat='FULL_CONTENT', # or 'METADATA' when bodies are not needed @@ -119,7 +119,7 @@ created via this backend always start a new conversation on the subject + `In-Reply-To` / `References` matching, which usually works but is not guaranteed. -``` +```text mcp__claude_ai_Gmail__create_draft( subject='Re: ', to=[''], @@ -184,7 +184,7 @@ For the ASF-security-relay special case (different `to` / ### List drafts -``` +```text mcp__claude_ai_Gmail__list_drafts( query='', # e.g. 'list:' ) diff --git a/tools/gmail/ponymail-archive.md b/tools/gmail/ponymail-archive.md index 8efaa259..82ace913 100644 --- a/tools/gmail/ponymail-archive.md +++ b/tools/gmail/ponymail-archive.md @@ -51,7 +51,7 @@ Placeholder convention: ### Archive search (query returns a list-page with matching threads) -``` +```text https://lists.apache.org/list?:YYYY-M: ``` @@ -64,13 +64,13 @@ https://lists.apache.org/list?:YYYY-M: Alternative bare URL form used by the sync skill when scanning the public archive for a CVE ID: -``` +```text https://lists.apache.org/list.html?:YYYY: ``` ### Archive API (JSON response, the sync skill uses this first) -``` +```text https://lists.apache.org/api/thread.lua?list=&domain=&q= ``` @@ -83,7 +83,7 @@ public lists. ### Resolved thread URL (what the skill records in the tracker) -``` +```text https://lists.apache.org/thread/? ``` @@ -105,7 +105,7 @@ the archive URL programmatically. Instead, the skill **constructs** the search URL for the month the message was received and proposes it to the user at Step 5 as a one-click lookup: -``` +```text https://lists.apache.org/list?:YYYY-M: ``` diff --git a/tools/ponymail/operations.md b/tools/ponymail/operations.md index 4f95cab0..0d632fc4 100644 --- a/tools/ponymail/operations.md +++ b/tools/ponymail/operations.md @@ -60,7 +60,7 @@ Every skill that talks to PonyMail MCP does a one-call pre-flight in Step 0 to verify the session is authenticated before relying on private-list queries: -``` +```text mcp__ponymail__auth_status() ``` @@ -79,7 +79,7 @@ auth tools: ### Login -``` +```text mcp__ponymail__login() ``` @@ -90,7 +90,7 @@ Code session pick up the cached cookie automatically. ### Auth status -``` +```text mcp__ponymail__auth_status() ``` @@ -101,7 +101,7 @@ handled by the [Error handling](#error-handling) section below. ### Logout -``` +```text mcp__ponymail__logout() ``` @@ -113,7 +113,7 @@ logout on their own — it is a user-driven lifecycle step. ### List lists -``` +```text mcp__ponymail__list_lists() ``` @@ -133,7 +133,7 @@ the MCP itself, so repeat invocations are fast. ### Search a list -``` +```text mcp__ponymail__search_list( list: "", domain: "", @@ -180,7 +180,7 @@ tid) — not full bodies. Fetch the body via ### Get a thread -``` +```text mcp__ponymail__get_thread( list: "", domain: "", @@ -200,7 +200,7 @@ conversation. ### Get an email -``` +```text mcp__ponymail__get_email( id: "" ) @@ -216,7 +216,7 @@ reference) and want its full body. ### Get an mbox dump -``` +```text mcp__ponymail__get_mbox( list: "", domain: "", @@ -245,7 +245,7 @@ Until then, common recipes: ### Find the advisory archive thread on `users@.apache.org` -``` +```text mcp__ponymail__search_list( list: "users", domain: ".apache.org", @@ -262,7 +262,7 @@ for the tracker's *Public advisory URL* body field. ### Pull the original report thread on `security@.apache.org` -``` +```text mcp__ponymail__search_list( list: "security", domain: ".apache.org", @@ -277,7 +277,7 @@ string — same heuristic as the Gmail equivalent in ### Find the `[RESULT][VOTE]` thread for a release -``` +```text mcp__ponymail__search_list( list: "dev", domain: ".apache.org", diff --git a/tools/ponymail/tool.md b/tools/ponymail/tool.md index 42893aba..d28ec4d5 100644 --- a/tools/ponymail/tool.md +++ b/tools/ponymail/tool.md @@ -152,7 +152,7 @@ is picked up and its tools appear in the deferred-tool list. In a Claude Code session, run: -``` +```text mcp__ponymail__login() ``` @@ -164,7 +164,7 @@ Code sessions until the cookie expires. Verify: -``` +```text mcp__ponymail__auth_status() ``` @@ -177,7 +177,7 @@ lists but returns empty results for private-list queries. Pull the list overview to confirm the session sees the expected lists: -``` +```text mcp__ponymail__list_lists() ``` diff --git a/tools/vulnogram/allocation.md b/tools/vulnogram/allocation.md index 1df69ab2..1e65e5da 100644 --- a/tools/vulnogram/allocation.md +++ b/tools/vulnogram/allocation.md @@ -29,7 +29,7 @@ ID) lives in ## Allocation URL -``` +```text https://cveprocess.apache.org/allocatecve ```