This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow-steward.git
The following commit(s) were added to refs/heads/main by this push:
new 5eee612 docs: enable markdownlint MD040 and tag all fenced code
blocks (supersedes #30) (#44)
5eee612 is described below
commit 5eee612551d0c15946af43262b692760c0f4e36c
Author: Jarek Potiuk <[email protected]>
AuthorDate: Mon May 4 12:11:58 2026 +0200
docs: enable markdownlint MD040 and tag all fenced code blocks (supersedes
#30) (#44)
* docs: enable markdownlint MD040 and tag all fenced code blocks
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 <details> 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 <[email protected]>
* docs: extend MD040 tagging to skills added since #30
#30 was opened against an earlier tree state; the pr-management
skill family (lifted in #33, renamed to type-what-action in
#35) added 9 new skill supporting files with 20 untagged
fences that fail markdownlint MD040 once it's enabled.
This commit applies the same tagging convention #30 established
for the security family + tools to the new pr-management files:
pr-management-triage/fetch-and-batch.md 1 fence
pr-management-triage/comment-templates.md 2 fences → markdown
pr-management-triage/interaction-loop.md 4 fences → text (UI mockups)
pr-management-triage/workflow-approval.md 2 fences → text (UI mockups)
pr-management-stats/fetch.md 3 fences → text (search
queries)
pr-management-stats/render.md 3 fences → text (output
samples)
pr-management-stats/classify.md 3 fences → text (pseudocode)
pr-management-code-review/review-flow.md 1 fence → text (CLI mockup)
pr-management-code-review/prerequisites.md 1 fence → text (HTTP error)
Most fences ended up `text` (the same catch-all #30's commit
message used for "MCP call sketches, URL examples, dir trees,
plain output"). Two `markdown` fences in
`pr-management-triage/comment-templates.md` because the
content is a markdown link / list item example that GitHub
should render as markdown.
prek run --all-files clean. MD040 reports zero violations
across the tree.
Generated-by: Claude Code (Claude Opus 4.7)
---------
Signed-off-by: André Ahlert <[email protected]>
Co-authored-by: André Ahlert <[email protected]>
---
.../pr-management-code-review/prerequisites.md | 2 +-
.../pr-management-code-review/review-flow.md | 2 +-
.claude/skills/pr-management-stats/classify.md | 6 +++---
.claude/skills/pr-management-stats/fetch.md | 6 +++---
.claude/skills/pr-management-stats/render.md | 6 +++---
.../pr-management-triage/comment-templates.md | 4 ++--
.../skills/pr-management-triage/fetch-and-batch.md | 2 +-
.../pr-management-triage/interaction-loop.md | 8 ++++----
.../pr-management-triage/workflow-approval.md | 4 ++--
.claude/skills/security-cve-allocate/SKILL.md | 6 +++---
.claude/skills/security-issue-fix/SKILL.md | 2 +-
.../skills/security-issue-import-from-md/SKILL.md | 12 +++++------
.../skills/security-issue-import-from-pr/SKILL.md | 6 +++---
.claude/skills/security-issue-import/SKILL.md | 6 +++---
.claude/skills/security-issue-invalidate/SKILL.md | 6 +++---
.claude/skills/security-issue-sync/SKILL.md | 14 ++++++-------
.markdownlint.json | 8 ++++----
AGENTS.md | 12 +++++------
CONTRIBUTING.md | 2 +-
docs/setup/secure-agent-setup.md | 4 ++--
projects/_template/fix-workflow.md | 2 +-
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 +-
28 files changed, 90 insertions(+), 90 deletions(-)
diff --git a/.claude/skills/pr-management-code-review/prerequisites.md
b/.claude/skills/pr-management-code-review/prerequisites.md
index 54784ba..097146e 100644
--- a/.claude/skills/pr-management-code-review/prerequisites.md
+++ b/.claude/skills/pr-management-code-review/prerequisites.md
@@ -25,7 +25,7 @@ the target repo (`<upstream>` by default). Without
collaborator access, the eventual `gh pr review` mutation in
[`posting.md`](posting.md) returns:
-```
+```text
HTTP 403: Resource not accessible by integration
```
diff --git a/.claude/skills/pr-management-code-review/review-flow.md
b/.claude/skills/pr-management-code-review/review-flow.md
index 3d95e15..b0d72a8 100644
--- a/.claude/skills/pr-management-code-review/review-flow.md
+++ b/.claude/skills/pr-management-code-review/review-flow.md
@@ -28,7 +28,7 @@ multi-line headline. Per Golden rule 10 in `SKILL.md`, the PR
number is always printed alongside its full URL so the
maintainer can click straight through:
-```
+```text
PR #65934 — Fix scheduler N+1 on serialized Dag load
https://github.com/<upstream>/pull/65934
Author: alice (CONTRIBUTOR, [external])
diff --git a/.claude/skills/pr-management-stats/classify.md
b/.claude/skills/pr-management-stats/classify.md
index 71c01ef..a3a0785 100644
--- a/.claude/skills/pr-management-stats/classify.md
+++ b/.claude/skills/pr-management-stats/classify.md
@@ -91,7 +91,7 @@ Mark which path the skill used in the legend output (`drafted
by triager (heuris
The age of a PR for bucketing is the time since the author's *last
interaction*:
-```
+```text
last_author_interaction = max(
most_recent_comment.createdAt where comment.author.login ==
pr.author.login,
last_commit.committedDate,
@@ -120,7 +120,7 @@ Four buckets is the deliberate minimum — each one maps to a
distinct maintaine
A PR is by a *contributor* (for the `Contrib.` column) when:
-```
+```text
authorAssociation NOT IN (OWNER, MEMBER, COLLABORATOR)
```
@@ -138,7 +138,7 @@ The `Ready` column counts PRs carrying the `ready for
maintainer review` label.
Table 1's `Responded` column measures, per area, how many triaged PRs got an
author reply *before* they were closed or merged. For a PR in the closed-since
set:
-```
+```text
responded_before_close =
is_triaged AND
exists(comment by pr.author where comment.createdAt >
triage_comment.createdAt AND comment.createdAt <= pr.closedAt)
diff --git a/.claude/skills/pr-management-stats/fetch.md
b/.claude/skills/pr-management-stats/fetch.md
index b552cb5..78eff1d 100644
--- a/.claude/skills/pr-management-stats/fetch.md
+++ b/.claude/skills/pr-management-stats/fetch.md
@@ -55,7 +55,7 @@ query(
### `searchQuery`
-```
+```text
is:pr is:open repo:<repo> sort:created-asc
```
@@ -199,7 +199,7 @@ Empirical delta on `<upstream>`, cutoff 2026-03-11:
When the maintainer explicitly asks for a quick approximation (`fast-closed`
flag, or in a low-budget context), fall back to the search-based path:
-```
+```text
is:pr -is:open repo:<repo> closed:>=<cutoff> sort:updated-desc
```
@@ -207,7 +207,7 @@ The fast path must print a clear caveat above Table 1:
*"fast-closed mode: Table
### `searchQuery`
-```
+```text
is:pr -is:open repo:<repo> closed:>=<cutoff> sort:updated-desc
```
diff --git a/.claude/skills/pr-management-stats/render.md
b/.claude/skills/pr-management-stats/render.md
index 5c1b996..9f57ae7 100644
--- a/.claude/skills/pr-management-stats/render.md
+++ b/.claude/skills/pr-management-stats/render.md
@@ -121,7 +121,7 @@ Counts must sum to the open-PR total (non-bot). If they
don't, print a warning a
Before the first table, print one line summarising the scope. This line is
plain text (no Rich markup needed — it's header-style, not a table) so it
renders identically in the terminal and in the Markdown fallback.
-```
+```text
<upstream> — 413 open PRs (non-bot) · closed/merged since 2026-03-11 · viewer
@potiuk · 2026-04-22 22:33 UTC
```
@@ -131,7 +131,7 @@ The `<now>` is the fetch-start timestamp, not the
render-end timestamp — a slo
If the closed-since counts came from the lagging search index (see
[`fetch.md#known-limitation`](fetch.md)), print a one-line caveat between the
context line and Table 1:
-```
+```text
⚠ Table 1 built from GitHub's free-text search of the quality-criteria marker.
The index lags — older triaged+merged PRs are likely undercounted. Pass
accurate-closed for the hybrid REST + GraphQL path.
```
@@ -229,7 +229,7 @@ console.print(Panel("\n".join(legend_lines),
border_style="dim", expand=False))
Close with a single-line summary the maintainer can use for at-a-glance
reporting:
-```
+```text
Summary: 413 open · 66 triaged (16%) · 3 responded (5% of triaged) · 126 ready
for review · 43 drafted by triager in last 7d.
```
diff --git a/.claude/skills/pr-management-triage/comment-templates.md
b/.claude/skills/pr-management-triage/comment-templates.md
index b471bac..b289da5 100644
--- a/.claude/skills/pr-management-triage/comment-templates.md
+++ b/.claude/skills/pr-management-triage/comment-templates.md
@@ -26,7 +26,7 @@ Placeholders:
All templates use the canonical link to the quality-criteria
document:
-```
+```markdown
[Pull Request quality
criteria](https://github.com/<upstream>/blob/main/contributing-docs/05_pull_requests.rst#pull-request-quality-criteria)
```
@@ -421,7 +421,7 @@ bad-faith actor a footnote to argue with.
one bullet per violation returned by the classifier. Each
bullet has the form:
-```
+```markdown
- :x: **<category>** — <explanation>. See [docs](<doc_link>).
```
diff --git a/.claude/skills/pr-management-triage/fetch-and-batch.md
b/.claude/skills/pr-management-triage/fetch-and-batch.md
index 13a74e4..c4d7f91 100644
--- a/.claude/skills/pr-management-triage/fetch-and-batch.md
+++ b/.claude/skills/pr-management-triage/fetch-and-batch.md
@@ -119,7 +119,7 @@ query(
below. The typical production shape for the default sweep on
`<upstream>` is:
-```
+```text
is:pr is:open repo:<upstream>
-label:"ready for maintainer review"
sort:updated-asc
diff --git a/.claude/skills/pr-management-triage/interaction-loop.md
b/.claude/skills/pr-management-triage/interaction-loop.md
index ecb897c..b4cbe79 100644
--- a/.claude/skills/pr-management-triage/interaction-loop.md
+++ b/.claude/skills/pr-management-triage/interaction-loop.md
@@ -74,7 +74,7 @@ For each group, present one screen of information. The goal is
a decision in under 15 seconds when the suggestion looks right,
or a natural path to per-PR inspection when it doesn't.
-```
+```text
─────────────────────────────────────────────────────
Group 3 of 8 — deterministic_flag → draft — 5 PRs
@@ -155,7 +155,7 @@ step in place of `[A]`/`[E]`.
When a PR is pulled out of a group (via `[P]`, `[E]`, or
because its group mandates per-PR), present the full detail:
-```
+```text
─────────────────────────────────────────────────────
PR #65471 "Add support for new db dialect"
Author: @eve (tier: new, 2 merged / 5 total on this repo)
@@ -307,7 +307,7 @@ the drill-in, it's instant.
When `[A]` triggers batched mutations, show live progress as a
short table that updates in-place:
-```
+```text
Applying action: draft (5 PRs, parallelism: 5)
#65401 @alice — posting comment… done
@@ -330,7 +330,7 @@ before moving on.
On exit (either `[Q]` or after the last group), print a
session summary:
-```
+```text
Session summary — 2026-04-22 09:42 UTC → 10:07 UTC (25m)
PRs presented: 47
diff --git a/.claude/skills/pr-management-triage/workflow-approval.md
b/.claude/skills/pr-management-triage/workflow-approval.md
index 601a808..e230b87 100644
--- a/.claude/skills/pr-management-triage/workflow-approval.md
+++ b/.claude/skills/pr-management-triage/workflow-approval.md
@@ -160,7 +160,7 @@ For each PR in the group, in the order returned by the
classifier (which is age-ascending so the freshest PRs land
first), print:
-```
+```text
─────────────────────────────────────────────────────
[N] PR #NNNNN "<title>"
Author: @<login> (account: D days old, R repos, M merged PRs)
@@ -192,7 +192,7 @@ patterns matched"*. That's the green-light
pre-classification.
After all blocks are printed, render the summary table and
prompt for selection:
-```
+```text
─────────────────────────────────────────────────────
pending_workflow_approval — N PRs · choose what to approve
─────────────────────────────────────────────────────
diff --git a/.claude/skills/security-cve-allocate/SKILL.md
b/.claude/skills/security-cve-allocate/SKILL.md
index 78ca386..39652c4 100644
--- a/.claude/skills/security-cve-allocate/SKILL.md
+++ b/.claude/skills/security-cve-allocate/SKILL.md
@@ -305,14 +305,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
[<tracker>#<N>](https://github.com/<tracker>/issues/<N>).**
1. Open the ASF Vulnogram allocation form:
<https://cveprocess.apache.org/allocatecve>
2. In the *Title* field, paste this:
- ```
+ ```text
<stripped title>
```
@@ -326,7 +326,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/security-issue-fix/SKILL.md
b/.claude/skills/security-issue-fix/SKILL.md
index 3d8ca2b..b25ead4 100644
--- a/.claude/skills/security-issue-fix/SKILL.md
+++ b/.claude/skills/security-issue-fix/SKILL.md
@@ -462,7 +462,7 @@ Write out the exact `--body` the skill will pass to
- the standard Gen-AI disclosure block per
[`<upstream>/contributing-docs/05_pull_requests.rst`](https://github.com/<upstream>/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/security-issue-import-from-md/SKILL.md
b/.claude/skills/security-issue-import-from-md/SKILL.md
index f2c2847..a3ed0db 100644
--- a/.claude/skills/security-issue-import-from-md/SKILL.md
+++ b/.claude/skills/security-issue-import-from-md/SKILL.md
@@ -286,7 +286,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 ] <finding title>
```
@@ -377,7 +377,7 @@ exactly one blank line before `</details>`.
Render a single proposal covering every parsed finding:
-```
+```text
<file-basename> — N findings parsed.
| # | Severity | Category | Title
| Possible duplicate |
@@ -581,7 +581,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] <tracker>#NNN — <finding title>
```
@@ -661,7 +661,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
```
@@ -675,7 +675,7 @@ reference.
### Example 2 — A single-finding scanner export
-```
+```text
import findings from ~/Downloads/sast-export.md
```
@@ -686,7 +686,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/security-issue-import-from-pr/SKILL.md
b/.claude/skills/security-issue-import-from-pr/SKILL.md
index db0071b..8fb4c10 100644
--- a/.claude/skills/security-issue-import-from-pr/SKILL.md
+++ b/.claude/skills/security-issue-import-from-pr/SKILL.md
@@ -710,7 +710,7 @@ with other trackers.
### Example 1 — `providers` scope, already merged
-```
+```text
import from pr 65703
```
@@ -729,7 +729,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/<upstream>/pull/65999
```
@@ -742,7 +742,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/security-issue-import/SKILL.md
b/.claude/skills/security-issue-import/SKILL.md
index 696d57e..1ff9f17 100644
--- a/.claude/skills/security-issue-import/SKILL.md
+++ b/.claude/skills/security-issue-import/SKILL.md
@@ -250,7 +250,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: "<project>.apache.org",
@@ -481,7 +481,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 <threadId> — "<candidate title>"
- GHSA match: [#NNN](...) "GHSA-xxxx-yyyy-zzzz" (STRONG)
- Code-pointer match: [#MMM](...) "BaseSerialization.deserialize" (MEDIUM)
@@ -553,7 +553,7 @@ authenticated (Step 0) **and**
`security@<project>.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: "<project>.apache.org",
diff --git a/.claude/skills/security-issue-invalidate/SKILL.md
b/.claude/skills/security-issue-invalidate/SKILL.md
index 9e5f897..a98f96e 100644
--- a/.claude/skills/security-issue-invalidate/SKILL.md
+++ b/.claude/skills/security-issue-invalidate/SKILL.md
@@ -658,7 +658,7 @@ Hand-off line:
### Example 1 — `security@`-imported, dag-author-input class
-```
+```text
invalidate 244
```
@@ -676,7 +676,7 @@ verbatim quotes and the draft ID. Hand-off: terminal.
### Example 2 — PR-imported, no email
-```
+```text
invalidate 355
```
@@ -694,7 +694,7 @@ import-from-pr skill's golden rules.
### Example 3 — Hard stop: CVE already allocated
-```
+```text
invalidate 257
```
diff --git a/.claude/skills/security-issue-sync/SKILL.md
b/.claude/skills/security-issue-sync/SKILL.md
index 2bd573f..e700eaf 100644
--- a/.claude/skills/security-issue-sync/SKILL.md
+++ b/.claude/skills/security-issue-sync/SKILL.md
@@ -237,7 +237,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: <N>
title: <one line>
scope_label: airflow | providers | chart | <missing>
@@ -481,7 +481,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: "<project>.apache.org",
@@ -723,7 +723,7 @@ authenticated (Step 0) **and**
`security@<project>.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: "<project>.apache.org",
@@ -1115,7 +1115,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: "<project>.apache.org",
@@ -1497,7 +1497,7 @@ will change and *why*. Group them by category:
**Idempotency.** Before proposing, scan the issue's existing
comments for the marker
- ```
+ ```html
<!-- apache-steward: release-manager-handoff v1 -->
```
exactly. If a comment carrying this marker already exists, **do
@@ -1579,7 +1579,7 @@ will change and *why*. Group them by category:
**Idempotency.** Before proposing, scan the issue's existing
comments for the marker
- ```
+ ```html
<!-- apache-steward: release-manager-publication-ready v1 -->
```
exactly. If a comment carrying this marker already exists, do not
@@ -1666,7 +1666,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: "<project-domain>",
diff --git a/.markdownlint.json b/.markdownlint.json
index a336c7d..5bc76c3 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 76b0926..8caf4de 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -235,7 +235,7 @@ at the root of its tracker repository. The framework refers
to this
directory via the placeholder `<project-config>`. Concretely, an
adopting project lays out:
-```
+```text
<adopter-tracker-repo>/
└── .apache-steward/
├── apache-steward/ # (submodule) clone of this framework
@@ -374,13 +374,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: <agent name and version>
```
Concrete example for Claude Code:
- ```
+ ```text
Generated-by: Claude Code (Opus 4.7)
```
@@ -862,7 +862,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/<CVE-ID>
```
@@ -876,7 +876,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=<CVE-ID>
```
@@ -967,7 +967,7 @@ messages, internal notes, `SKILL.md` files — render it as a
**clickable markdown link**, not as a bare `#NNN` or
`<tracker>#NNN`. The URL format is:
-```
+```text
https://github.com/<tracker>/issues/<N>
https://github.com/<tracker>/pull/<N>
https://github.com/<tracker>/issues/<N>#issuecomment-<C>
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3117a71..d403615 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/docs/setup/secure-agent-setup.md b/docs/setup/secure-agent-setup.md
index 532556f..cc79cbd 100644
--- a/docs/setup/secure-agent-setup.md
+++ b/docs/setup/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/projects/_template/fix-workflow.md
b/projects/_template/fix-workflow.md
index ec1f447..0a87bb7 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/tools/github/status-rollup.md b/tools/github/status-rollup.md
index 0d28b8f..1ea00d2 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
<old body>
---
@@ -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
<!-- airflow-s status rollup v1 — all bot-authored status updates fold into
this single comment. -->
<new entry>
```
@@ -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 `<details>` envelope:
- ```
+ ```html
<details><summary><createdAt date> · @<author.login> · <Action></summary>
<legacy body — verbatim, left-trimmed>
diff --git a/tools/gmail/draft-backends.md b/tools/gmail/draft-backends.md
index ff64002..92fffe3 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: "<inbound-thread-id>",
messageFormat: MINIMAL)
```
diff --git a/tools/gmail/operations.md b/tools/gmail/operations.md
index c45a735..0d75e26 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:<security-list-domain>',
pageSize=1,
@@ -65,7 +65,7 @@ fix the setup rather than guessing.
### Search threads
-```
+```text
mcp__claude_ai_Gmail__search_threads(
query='<gmail search expression>',
pageSize=<N>,
@@ -82,7 +82,7 @@ the skills use, see [`search-queries.md`](search-queries.md).
### Get thread
-```
+```text
mcp__claude_ai_Gmail__get_thread(
threadId='<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: <root subject of the inbound message>',
to=['<primary>'],
@@ -184,7 +184,7 @@ For the ASF-security-relay special case (different `to` /
### List drafts
-```
+```text
mcp__claude_ai_Gmail__list_drafts(
query='<optional filter>', # e.g. 'list:<security-list-domain>'
)
diff --git a/tools/gmail/ponymail-archive.md b/tools/gmail/ponymail-archive.md
index 0fbd9b2..b9edbd5 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?<list>:YYYY-M:<url-encoded search>
```
@@ -64,13 +64,13 @@ https://lists.apache.org/list?<list>:YYYY-M:<url-encoded
search>
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?<list>:YYYY:<CVE-ID>
```
### Archive API (JSON response, the sync skill uses this first)
-```
+```text
https://lists.apache.org/api/thread.lua?list=<list-local>&domain=<list-domain>&q=<search>
```
@@ -83,7 +83,7 @@ public lists.
### Resolved thread URL (what the skill records in the tracker)
-```
+```text
https://lists.apache.org/thread/<hash>?<list>
```
@@ -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?<security-list>:YYYY-M:<url-encoded subject>
```
diff --git a/tools/ponymail/operations.md b/tools/ponymail/operations.md
index 62176d9..9afac56 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: "<list>",
domain: "<domain>",
@@ -180,7 +180,7 @@ tid) — not full bodies. Fetch the body via
### Get a thread
-```
+```text
mcp__ponymail__get_thread(
list: "<list>",
domain: "<domain>",
@@ -200,7 +200,7 @@ conversation.
### Get an email
-```
+```text
mcp__ponymail__get_email(
id: "<mid or Message-ID header value>"
)
@@ -216,7 +216,7 @@ reference) and want its full body.
### Get an mbox dump
-```
+```text
mcp__ponymail__get_mbox(
list: "<list>",
domain: "<domain>",
@@ -245,7 +245,7 @@ Until then, common recipes:
### Find the advisory archive thread on `users@<project>.apache.org`
-```
+```text
mcp__ponymail__search_list(
list: "users",
domain: "<project>.apache.org",
@@ -262,7 +262,7 @@ for the tracker's *Public advisory URL* body field.
### Pull the original report thread on `security@<project>.apache.org`
-```
+```text
mcp__ponymail__search_list(
list: "security",
domain: "<project>.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: "<project>.apache.org",
diff --git a/tools/ponymail/tool.md b/tools/ponymail/tool.md
index 42893ab..d28ec4d 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 4004a64..846a3a7 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
```