Repository navigation
doc: replace doc/design with an architecture-only design guide - #529
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The guide contains stale network and filesystem behavior and has not yet incorporated the current virtio-fs architecture.
4 open findings
What changed in this PR
Adds a standalone, architecture-focused NVX design guide organized by concepts rather than implementation components.
Changes:
- Documents machine architecture, devices, guest runtime, and lifecycle.
- Defines compatibility, trust boundaries, configuration ownership, and snapshot semantics.
- Adds navigable chapter and section indexes.
| File | Description |
|---|---|
doc/design-doc/README.md |
Indexes the architecture guide. |
doc/design-doc/1-architecture-overview.md |
Introduces the architecture. |
doc/design-doc/1.1-goals.md |
Defines architectural goals. |
doc/design-doc/1.2-non-goals.md |
Defines excluded capabilities. |
doc/design-doc/1.3-system-components-and-responsibilities.md |
Assigns component responsibilities. |
doc/design-doc/1.4-trust-boundaries.md |
Documents trust and validation boundaries. |
doc/design-doc/1.5-compatibility-and-versioning-model.md |
Defines compatibility contracts. |
doc/design-doc/2-virtual-machine-architecture.md |
Indexes the machine architecture. |
doc/design-doc/2.1-machine-model-and-configuration.md |
Defines machine configuration ownership. |
doc/design-doc/2.2-cpu-and-topology.md |
Documents CPU profiles and topology. |
doc/design-doc/2.3-memory-layout.md |
Defines guest memory layout. |
doc/design-doc/2.4-interrupt-and-io-architecture.md |
Describes interrupt and I/O paths. |
doc/design-doc/2.5-device-topology-transport-and-discovery.md |
Defines fixed device topology. |
doc/design-doc/3-virtual-devices.md |
Indexes virtual devices. |
doc/design-doc/3.1-platform-control-device.md |
Documents platform-control ports. |
doc/design-doc/3.2-clock-and-time.md |
Defines the time ABI. |
doc/design-doc/3.3-consoles.md |
Documents boot and control consoles. |
doc/design-doc/3.4-block-storage.md |
Defines block roles and behavior. |
doc/design-doc/3.5-network.md |
Documents networking and policy. |
doc/design-doc/3.6-host-filesystem.md |
Documents host filesystem exports. |
doc/design-doc/4-guest-runtime-architecture.md |
Indexes guest runtime architecture. |
doc/design-doc/4.1-guest-filesystem-and-image-model.md |
Describes workload filesystem construction. |
doc/design-doc/4.2-guest-agents-and-workload-model.md |
Defines workload supervision. |
doc/design-doc/4.3-isolation-and-resource-model.md |
Documents guest isolation. |
doc/design-doc/4.4-host-guest-control-interface.md |
Defines the control protocol. |
doc/design-doc/5-vm-lifecycle-and-state.md |
Indexes lifecycle and state. |
doc/design-doc/5.1-boot-protocol.md |
Defines boot behavior. |
doc/design-doc/5.2-readiness-and-runtime-control.md |
Documents readiness and control. |
doc/design-doc/5.3-snapshot-protocol.md |
Defines snapshot capture. |
doc/design-doc/5.4-snapshot-artifact-and-attachment-model.md |
Defines snapshot artifacts and attachments. |
doc/design-doc/5.5-restore-protocol.md |
Defines restore and guest repair. |
doc/design-doc/5.6-shutdown-and-failure-semantics.md |
Defines shutdown and failures. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
56992b1 to
7d31389
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Network ingress, virtio-fs, and mapped-file sections contradict behavior already merged into the codebase.
6 open findings
Attachment list omits listeners rejected during snapshot restore · New Architecture guide omits merged FUSE and HostFs request architecture · New Include private-network ingress listeners in the attachment contract Correct file export model to describe per-file aggregate children Correct minimum FUSE protocol versions for cold boot and restore Update ingress allow behavior to match the current network contract
🧠 Review effort: Balanced
7d31389 to
5a6995c
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Several passages incorrectly describe restore failure, virtio-fs caching, and exit-status semantics.
3 open findings
6 resolved since last review
Architecture guide omits merged FUSE and HostFs request architecture Attachment list omits listeners rejected during snapshot restore Include private-network ingress listeners in the attachment contract Correct file export model to describe per-file aggregate children Correct minimum FUSE protocol versions for cold boot and restore Update ingress allow behavior to match the current network contract
🧠 Review effort: Balanced
5a6995c to
5dd1709
Compare
3194e86 to
4760118
Compare
4760118 to
1d898bf
Compare
#529 replaced doc/design with the architecture guide and removed doc/design/time-abi.md, the time ABI specification. NVX code, tests, and documentation, and OpenVMM's time ABI comments, still cited it: its sections, its snapshot-agent and restore step numbers, and check IDs that no remaining document defines. Retarget every NVX citation to the guide, fold the specification's remaining architecture-level detail into section 3.2, leave its implementation detail to the code that defines it, and pin an OpenVMM revision whose documentation no longer depends on NVX's documents. Folded into 3.2.10 (Guest Obligations): - Which checks capture and restore rerun, instead of "the relevant subset": capture reruns the clocksource, tick-device, and watcher checks; restore reruns them, checks the declared rate in the frequency MSR again, and checks the identity leaves, CPU time bits, and CPU flags of every processor that it brings online. - What the state file reports: the outcome of each phase's checks, the declared rates, the generation, the last downtime and its source, and the wall clock's discontinuities, synchronization, offset, uncertainty, and frequency correction. - Restore repair and the discipline step the clock through the kernel, so a workload observes every step through the kernel's clock-set notification, such as a timerfd armed with TFD_TIMER_CANCEL_ON_SET. The rest of the specification's architecture-level content is already in the guide: the guest's fail-fast statuses (5.6), generations (5.5.6), the rejection of clock tokens in the command line (5.1), and capture rollback (5.3). Its implementation detail stays out of the documentation: the E_* and G_* codes, the check IDs C1 to C12, K1, and X1 to X6, the NVX-TIME-ABI line formats, the state file's path and keys, the watcher's kernel log patterns, report-only mode, and the warp probe's method. guest/common/nvx-time.c now states that it defines its check IDs, guest codes, output lines, and state file format. Renumbered snapshot-agent steps: - guest/common/nvx-time.c, guest/common/nvx-snapshot, and scripts/test_microvm_tests.py number the snapshot agent's steps as the guide does: guest preparation steps 1 to 4 (5.3.2) and guest repair steps 1 to 7 (5.5.7), instead of the removed specification's capture steps 1 to 5 and restore steps 6 to 13. Old steps 6 to 10 are repair steps 1 to 5, old step 12 is repair step 6, and old step 13, with old step 11's checks, is repair step 7. - The comment on repair_restore names repair steps 2 and 3, because cmd_capture reads the status, repair step 1, itself. - Rename step13_cpu_ns, fork_step13, and test_step13_cpu to deferred_restore_cpu_ns, fork_deferred_restore, and test_deferred_restore_cpu, and nvx-time's "step13-cpu" test hook to "deferred-restore-cpu", with its test in scripts/test_guest_time.py. Retargeted documentation: - doc/build.md: the RCU stall timeout stays at its production value because the conformance checks cover the stall-detector settings (3.2.10), rather than because of check C8. - doc/ci.md: describe the exhaustive check's MSRs and the boot check of the debug detectors in words, rather than as checks C3 and C11. Retargeted code comments and test names, with no behavior change: - scripts/nvx_tools/doctor.py: the doctor runs its checks in ID order, as the --checks help text now says, and CHECK_CPU_BUDGET_US holds the CPU-time budgets. - scripts/nvx_tools/microvm_tests.py: the debug-kernel restore cases and the long-downtime case cite doc/ci.md. - scripts/nvx_tools/time_abi.py: the CPU profile catalog cites 2.2, and the warp probe check cites the 1 us skew bound of 3.2. - scripts/test_guest_time.py: the restore packet (5.5.5) and time sample (3.2.9) fixtures follow the guide, and the exhaustive check's lines and the state file fixtures pin the formats that nvx-time.c defines. The exhaustive-report test becomes test_exhaustive_report_format. - scripts/test_time_abi.py: the CPU-time budget comments no longer cite "the spec's" budgets. OpenVMM pin: Pin nanvix/openvmm#136 at c6d97c529986c0b3b1bf1fd7f00406654cdeee67, one commit on 7f225e2c. OpenVMM's time ABI comments cited the removed specification by path, by its "Backend obligations" table, by its step numbers, and as "the specification". They now state what the code does and refer only to OpenVMM's own items, and the three tests named after the specification are renamed. There is no behavior change. Index the new pin in doc/openvmm-upstream-roadmap.md. Fixes #562 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or an HTML href or src attribute, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README. An empty target, such as that of [Self](), links to its own document. - It resolves each anchor against the heading slugs that GitHub generates, including the numeric suffixes of repeated headings, and against HTML id and name attributes. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as CommonMark nests them in block quotes and list items, with lazy continuation lines, so that, as on GitHub, front matter, fenced and indented code, code spans, HTML comments and blocks, escaped brackets, and invalid reference definitions hold no links, while the definitions and headings inside block quotes and list items count. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or an HTML href or src attribute, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document. - It resolves each anchor against the heading slugs that GitHub generates, including the numeric suffixes of repeated headings, and against HTML id and name attributes. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as CommonMark nests them in block quotes and list items, with lazy continuation lines, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, code spans, HTML comments and blocks, and escaped brackets and tags hold no links, while the definitions and headings inside block quotes and list items count. - It parses each reference definition at the start of a paragraph whole, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. A reference link in a heading keeps its brackets in the anchor when no definition holds its label. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or an HTML href or src attribute, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document. - It resolves each anchor against the heading slugs that GitHub generates, including the numeric suffixes of repeated headings, and against HTML id and name attributes. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as CommonMark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, code spans, HTML comments and blocks, the attributes of raw HTML tags, link titles, and escaped brackets and tags hold no links, while the definitions and headings inside those containers count. A footnote renders, with its fn- and fnref- anchors, only when inline content cites it. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or an HTML href or src attribute, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document. - It resolves each anchor against the heading slugs that GitHub generates, including the numeric suffixes of repeated headings, and against HTML id and name attributes. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as CommonMark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, code spans, HTML comments and blocks, the attributes of raw HTML tags, link titles, image descriptions, and escaped brackets and tags hold no links, while the definitions and headings inside those containers count. A footnote renders, with its fn- and fnref- anchors, only when inline content cites it. - It matches brackets as CommonMark does, so links do not nest: an inner link leaves the brackets around it literal. Each cell of a table parses alone, and the cells past the header's count, which GitHub drops, hold no links. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or an HTML href or src attribute, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document. - It resolves each anchor against the slugs that GitHub generates from the rendered text of the headings, including the numeric suffixes of repeated headings, and against HTML id and name attributes. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as CommonMark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and HTML comments and blocks hold no links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. Each cell of a table parses alone, and the cells past the header's count, which GitHub drops, hold no links. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or an HTML href or src attribute, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document. - It resolves each anchor against the slugs that GitHub generates from the rendered text of the headings, including the numeric suffixes of repeated headings, and against HTML id and name attributes. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. Each cell of a table parses alone, and the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label. - It decodes a destination as cmark does, its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document. - It resolves each anchor against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. Each cell of a table parses alone, and the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label. - It decodes a destination as cmark does, its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document. - It resolves each anchor against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. Each cell of a table parses alone, and the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor, in lowercase as GitHub's script looks it up, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor, in lowercase as GitHub's script looks it up, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor as GitHub's script looks it up, in lowercase and with the user-content- prefix of the ids that GitHub renders, which the anchor may hold already, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor as GitHub's script looks it up, in lowercase and with the user-content- prefix of the ids that GitHub renders, which the anchor may hold already, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. A definition counts where it renders, and wherever a rendered reference uses it, even in a footnote that does not render. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor as GitHub's script looks it up, in lowercase and with the user-content- prefix of the ids that GitHub renders, which the anchor may hold already, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. A definition counts where it renders, and wherever a rendered reference uses it, even in a footnote that does not render. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor as GitHub's script looks it up, in lowercase and with the user-content- prefix of the ids that GitHub renders, which the anchor may hold already, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - As GitHub does, it slugs the text that each heading holds in the tree that libxml2's HTML parser builds from the rendered HTML. A start tag closes only the elements that libxml2 lets it close, so a paragraph's start tag closes a heading while a code block's does not, an end tag closes no element of a higher priority than its own, and a heading closes the heading that it starts in, so the text of a heading may run on across blocks. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. A definition counts where it renders, and wherever a rendered reference uses it, even in a footnote that does not render. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor as GitHub's script looks it up, in lowercase and with the user-content- prefix of the ids that GitHub renders, which the anchor may hold already, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - As GitHub does, it slugs the text that each heading holds in the tree that libxml2's HTML parser builds from the whole rendered document. A start tag closes only the elements that libxml2 lets it close, so a paragraph's start tag closes a heading while a code block's does not, an end tag closes no element of a higher priority than its own, and a heading closes the heading that it starts in. The text of a heading may thus run on across blocks, and the end tag of an element that an earlier block leaves open, such as a div, may close it. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. A definition counts where it renders, and wherever a rendered reference uses it, even in a footnote that does not render. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor as GitHub's script looks it up, in lowercase and with the user-content- prefix of the ids that GitHub renders, which the anchor may hold already, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - As GitHub does, it slugs the text that each heading holds in the tree that libxml2's HTML parser builds from the whole rendered document. A start tag closes only the elements that libxml2 lets it close, so a paragraph's start tag closes a heading while a code block's does not, an end tag closes no element of a higher priority than its own, and a heading closes the heading that it starts in. The text of a heading may thus run on across blocks, and the end tag of an element that an earlier block leaves open, such as a div, may close it. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. A definition counts where it renders, and wherever a rendered reference uses it, even in a footnote that does not render. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor as GitHub's script looks it up, in lowercase and with the user-content- prefix of the ids that GitHub renders, which the anchor may hold already, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - As GitHub does, it slugs the text that each heading holds in the tree that libxml2's HTML parser builds from the whole rendered document, where the paragraphs of tight lists, as cmark finds them, have no tags. A start tag closes only the elements that libxml2 lets it close, so a paragraph's start tag closes a heading while a code block's does not, an end tag closes no element of a higher priority than its own, and a heading closes the heading that it starts in. The text of a heading may thus run on across blocks, and the end tag of an element that an earlier block leaves open, such as a div, may close it. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. A definition counts where it renders, and wherever a rendered reference uses it, even in a footnote that does not render. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nothing in CI checked the repository's relative Markdown links. #529 moved the design documentation, numbered its sections, and retargeted every inbound link by hand, while an older link had already broken: the MXC integration table in aci_edge_sandboxes/README.md linked the anchor native-proxy-and-forwarded-ports of a heading that #512 had renamed to "Native proxy and host loopback". GitHub opens a page at its top when an anchor is missing, so such links break silently, and so do comments that cite a document by path, as the citations of the removed time ABI specification did (#562). Add scripts/check_markdown_links.py, a standard-library check, and run it in check-quality, whose job runs for every pull request that is ready for review, including the documentation-only ones that are most likely to break a link: - It resolves every relative link and image target of the tracked Markdown files, whether an inline link, a reference definition, or the href of an HTML link or src of an image, against the files that Git tracks, so a target that is untracked or differs in case, which GitHub cannot serve, fails too. A directory resolves, and its anchors are those of its README, whatever the README's case. An empty target, such as that of [Self](), links to its own document, and an image's anchor, such as GitHub's #gh-dark-mode-only, goes unchecked. - It resolves each anchor as GitHub's script looks it up, in lowercase and with the user-content- prefix of the ids that GitHub renders, which the anchor may hold already, against the slugs that GitHub generates from the rendered text of the Markdown and HTML headings, including the numeric suffixes of repeated headings, and against the id and name attributes of the HTML elements that GitHub keeps. Other files accept only line anchors, such as #L10, within their length. - It scans the blocks of each document as cmark nests them in block quotes, list items, and GitHub's footnote definitions, with lazy continuation lines and tabs that advance to the next multiple of four columns, and strips their markers before it parses inline content. As on GitHub, front matter, fenced and indented code, and the seven kinds of HTML blocks hold no Markdown links, while the definitions and headings inside those containers count. - It parses inline content left to right as CommonMark does: code spans, autolinks, including GitHub's bare ones, and raw HTML are atomic, each destination is consumed with its title, and brackets match so that links do not nest and an image's description holds no links. A footnote renders, with its fn- and fnref- anchors, only where inline content cites it. A table is a block of its own, which ends as GitHub's table extension ends it, and each of its cells parses alone, while the cells past the header's count, which GitHub drops, hold no links. - It tokenizes the raw HTML, in the order that GitHub renders it, as an HTML parser does, to find the tags whose attributes hold targets and anchors. A comment hides everything that renders up to its end, even in later blocks, while a CDATA section, processing instruction, or declaration ends at its first >. The tags that GitHub filters, such as <script> and <iframe>, render as text. - As GitHub does, it slugs the text that each heading holds in the tree that libxml2's HTML parser builds from the whole rendered document, where the paragraphs of tight lists, as cmark finds them, have no tags. A start tag closes only the elements that libxml2 lets it close, so a paragraph's start tag closes a heading while a code block's does not, an end tag closes no element of a higher priority than its own, and a heading closes the heading that it starts in. The text of a heading may thus run on across blocks, and the end tag of an element that an earlier block leaves open, such as a div, may close it. - It parses each reference definition at the start of a paragraph whole, within that paragraph, with its title, before the inline content that follows, and accepts any destination without spaces, as GitHub does. A definition counts where it renders, and wherever a rendered reference uses it, even in a footnote that does not render. In heading text, a reference link or image resolves only when a definition holds its label, a citation renders as its footnote's number, and the delimiters of emphasis and strikethrough match as cmark-gfm matches them, those of each link's text alone. - It decodes a destination as cmark does, trimmed and with its character references before its backslash escapes, and an HTML attribute as GitHub does, which keeps its backslashes, and its named references without semicolons, literal, and drops only the leading whitespace of a URL. As in HTML, the first attribute of each name hides the others. - Links into the openvmm submodule resolve against its pinned commit when it is checked out and are skipped otherwise, as in the quality job, whose checkout does not fetch submodules. - It also resolves, from the repository root, every doc/ path, with any anchor, that a tracked text file mentions. DOC_PATH_FIXTURES lists the test fixtures that name missing documents, such as doc/notes.md in scripts/test_nvx_tools.py, and an entry that its file no longer needs fails the check. A mention followed by a character that could extend the path, such as the * of a pattern, is ambiguous and is skipped. - It reports each problem with its file and line, as an error annotation in GitHub Actions, and then exits with status 1. scripts/test_markdown_links.py covers the slugs, the parsing, the resolution in temporary repositories, including a submodule, the fixtures, and the command line, and validate-nvx runs it on Linux and Windows. Retarget the README link to native-proxy-and-host-loopback, the only broken link that the check found, and document the check in doc/contribute.md, doc/setup.md, and doc/project-structure.md. Fixes #563 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>


Summary
This PR replaces
doc/design/with an architecture-only design guide that describes the NVX microVM and its single-workload guest runtime by architectural concept rather than by implementation component. The guide was developed asdoc/design-doc/and now lives atdoc/design/; the old component chapters and their index,doc/design.md, are removed. Start atdoc/design/README.md.Why
The old
doc/design/mixed the architecture with implementation detail: code paths, command-line options, tests and CI, measurements, status, current limits, and proposals. The guide keeps only the architecture, for readers who need the design without that detail. Keeping both would leave two diverging descriptions of the same system.What's in it
The README indexes five chapters. Each chapter page introduces its chapter and links its sections, and each section is a separate file named by its number, such as
2.2-cpu-and-topology.md.The guide leaves out code paths, command-line options, internal component names, tests, CI and host qualification, performance measurements, implementation status and current limits, and proposals.
Beyond reorganizing the old chapters, it:
Where the guide states the intended architecture ahead of the implementation, an issue tracks the gap:
distroandscratchroles; the implementation still acceptsruntimeandcustom.Removing the old chapters
doc/design.mdand the olddoc/design/chapters are deleted; they remain in the history.doc/design/copilot-adversarial-testing.mdmoves todoc/adversarial-testing.md. It is the operator document fortest-adversarial, not architecture, so it stays outside the guide.README.mdnow also lists the Ubuntu and Azure Linux guest chapters, which onlydoc/design.mdindexed.doc/ci.md, and the CPU-time budgets toCHECK_CPU_BUDGET_USinscripts/nvx_tools/time_abi.py.doc/design/time-abi.mdnow cite the guide ordoc/ci.md: thevalidate-runneraction,guest/common/nvx-snapshot,guest/common/nvx-time.c,scripts/nvx_tools/doctor.py(including the doctor's parser description),scripts/nvx_tools/host_time_probe.rs,scripts/nvx_tools/time_abi.py, andscripts/test_guest_time.py.Notes for reviewers
--helpdescription, there is no behavior change. Because comments inguest/common/andscripts/changed, CI runs the full matrix rather than the documentation-only path.doc/design/time-abi.mdin three comments (vmm_core/virt/src/time_abi/mod.rs,vmm_core/virt_kvm/src/arch/x86_64/time_abi.rs, andvmm_core/virt_whp/src/time_abi.rs). They need a separate OpenVMM change.doc/path that code mentions exists; LF line endings;ruff checkandruff format --check;scripts/test_time_abi.py,scripts/test_guest_time.py, andscripts/test_nvx_tools.py; andnvx.py doctor --help.cc Íñigo Goiri (@goiri) Enrique Saurez (@esaurez)