Artifact 56199865efb2572087b2ddb3632e5d88ce6b7db4bea7bac8d1e5b7e799b2f95a:
- File toolchains/kramdown-rfc-mechanics.md — part of check-in [3ba2975e8e] at 2026-07-07 14:05:17 on branch trunk — Split RFC workflow into neutral core and Fossil project pack (user: dmestas, size: 8089) [annotate] [blame] [check-ins using]
Kramdown RFC Mechanics
This note captures reusable mechanics for producing Internet-Draft or RFC outputs from kramdown-rfc source. It is intentionally limited to render and validation behavior. Local install steps, package-manager commands, and machine-specific setup belong in project-pack or operator notes, not here.
Scope
Use this note when a workflow produces:
- kramdown-rfc Markdown source;
- RFCXML v3 intermediate output; and
- rendered text, HTML, PDF, or related publication artifacts through xml2rfc.
The workflow owns the document content. This note owns the mechanical rules that keep source, rendered output, and validation behavior aligned.
Render pipeline
The toolchain has two stages:
kramdown-rfcconverts Markdown source to RFCXML v3.xml2rfcrenders the XML to text or other publishable formats.
Canonical render path:
kramdown-rfc -3 draft.md > draft.xml
xml2rfc --text draft.xml -o draft.txt
Common alternate outputs:
xml2rfc --html draft.xml -o draft.html
xml2rfc --pdf draft.xml -o draft.pdf
A clean kramdown-rfc run should leave stderr empty. A clean xml2rfc text render typically emits one Created file line. Treat extra stderr lines as warnings or errors that require disposition.
Required source structure
kramdown-rfc source has YAML front matter followed by body sections introduced with --- middle and, when needed, --- back.
Two structural rules matter mechanically:
- A blank line must precede every heading. Without the blank line, a heading can render as ordinary paragraph text and later fail at the xml2rfc stage.
- A blank line must precede each
--- middleand--- backseparator. Treat the separators as structural boundaries, not inline text.
Minimal safe shape:
---
title: Example Draft
submissiontype: STREAM-NAME
---
--- middle
# Introduction
Text.
--- back
Front-matter compatibility
Set front-matter fields so the stream and category agree with the intended publication target. Incompatible combinations may render with warnings or be rejected later.
At minimum, make these choices explicit in source:
submissiontype- intended status/category when the document type requires it
- document title, authors, and date fields expected by the publication target
Do not rely on tool defaults for stream selection.
BCP 14 requirement keywords
When the document uses RFC 2119 or RFC 8174 requirement keywords, include a dedicated Requirements Language section with tagged boilerplate:
## Requirements Language
{::boilerplate bcp14-tagged}
Mechanical rules:
- Use the boilerplate once per document.
- Do not also declare the same boilerplate-supplied references in the YAML header.
- Declare additional normative references, such as ABNF references, in the document metadata when required.
Literal character safety
Markdown and kramdown consume punctuation. Any literal protocol character, metacharacter, or grammar token that must survive into rendered output should appear in code spans, code blocks, or fenced examples.
After each render, verify that:
- literal operator characters survived unchanged;
- grammar punctuation rendered as written; and
- examples did not lose structural separators through wrapping or emphasis parsing.
References and cache behavior
Reference resolution can depend on cached bibxml data and network availability.
Reusable mechanics:
- Set and reuse
KRAMDOWN_REFCACHEwhen the workflow expects offline or repeatable reference resolution. - Treat a populated reference cache as part of render repeatability, not as public deliverable content.
- After rendering, inspect the rendered References section itself. A reference that appears in the table of contents but renders as an empty or incomplete body entry is unresolved even if the build succeeded.
Do not assume a successful render means every reference resolved correctly.
Warning triage
Warnings do not all mean the same thing.
Warnings that usually require action:
- declared but unused references;
- duplicate reference declarations;
- metadata or stream/category mismatches;
- structure errors that indicate a heading or section separator was parsed incorrectly.
Warnings that may be acceptable with explicit disposition:
- long source lines caused by quotations, hashes, URLs, or reproducible commands;
- wide artwork or wide sections when the rendered output remains readable and faithful.
A workflow should record which warnings were treated as blockers, which were accepted, and why.
Non-ASCII handling
Rendered output may contain non-ASCII characters introduced by source text, references, or boilerplate.
Reusable rules:
- Decide per run whether the target deliverable permits non-ASCII.
- If pure ASCII is required, normalize generated artifacts before final render and then verify the rendered deliverable for remaining non-ASCII codepoints.
- Be aware that boilerplate can introduce non-breaking spaces in generated XML even when rendered text later folds them to ordinary spaces.
- When non-ASCII is intentional, treat human names and quoted source material as explicit exceptions rather than silent drift.
Rendered-text-first example validation
Examples are not validated merely because the source Markdown looks correct.
For every public example:
- Render the draft.
- Extract the example from the rendered public text.
- Reconstruct the exact bytes or tokens that the rendered example claims.
- Re-run the relevant parser, decoder, comparison, or execution check against that rendered form.
- Confirm the rendered example still produces the stated result.
Mechanical risks to check explicitly:
- collapsed or hidden whitespace;
- lost separator newlines;
- wrapped lines that change counts or tokens;
- altered escaping;
- non-ASCII substitutions;
- rendered punctuation that differs from the source.
If the source example was correct but the rendered form no longer round-trips, the document is not ready.
Byte-counted or binary payload examples
Any example that embeds a length-counted, opaque, or binary payload needs extra handling.
Mechanical rules:
- State counts and separators in a way that survives rendered text.
- Do not let a visual line split imply payload structure the parser does not use.
- Validate such examples with a reader that honors the stated byte or token counts rather than a naive line splitter.
- Require at least one public hard-case example whose counted payload contains a separator byte, hidden whitespace edge, or non-text byte so a naive line splitter would misparse it.
- Prefer example layouts where a reviewer can see where counted payload begins and ends.
Publication-service fallback
When a local toolchain is unavailable or a second opinion is needed, the IETF Author Tools service can render and validate kramdown-rfc sources. Treat it as an alternate renderer, not as a replacement for local evidence discipline: the same rendered-text checks still apply.
Reusable verification checklist
Before a draft advances past mechanical validation, confirm:
- the Markdown source parses into the intended section structure;
- front matter matches the intended stream/category;
- boilerplate and references are not duplicated;
- rendered text preserves literal grammar characters;
- required sections and cross-references render correctly;
- examples round-trip from rendered public text, not just source form;
- byte-counted or binary hard cases prove the counting rule against a naive splitter;
- unresolved warnings have been dispositioned; and
- public outputs are separated from internal validation artifacts.
Escalate when
Stop and escalate when:
- render success depends on an undocumented local environment quirk;
- a warning changes output semantics rather than presentation only;
- rendered examples cannot be reconstructed faithfully;
- reference resolution differs across runs and changes the published text; or
- the chosen publication target requires metadata or formatting rules not yet captured in the workflow.