Repository navigation
fix(hygiene): use CommonMark for dead-link checks - #109
Conversation
Signed-off-by: Rio Yu <[email protected]>
Signed-off-by: Rio Yu <[email protected]>
chrisknvidia
left a comment
There was a problem hiding this comment.
Requesting changes. The intended CommonMark behavior works and the focused suite passes, but the current implementation introduces five blocking issue groups: unsafe local-path normalization, uncontained frontmatter failures, uncontained filesystem lookup failures, multiline diagnostic injection, and approximately quadratic malformed-HTML parsing. Please address the inline findings and add the specified regressions before merge.
Signed-off-by: Rio Yu <[email protected]>
Signed-off-by: Rio Yu <[email protected]>
Signed-off-by: Rio Yu <[email protected]>
|
Thanks for the detailed review. I've addressed the five groups and added regressions at the public validation/reporting boundaries:
I also merged upstream main at |
rng1995
left a comment
There was a problem hiding this comment.
Verified the five prior blocking findings are addressed by the follow-up commits. The focused hygiene, boundary, Markdown, and quality suites pass (288 tests). No new blocker found; the branch still needs its merge conflict resolved and checks rerun against current main.
Signed-off-by: Rio Yu <[email protected]>
|
Adding the numbers for point 5: on the same Linux host, 8/16/32/64 KiB took 9.0 / 19.1 / 42.1 / 100.7 ms after the guard, versus 108.8 / 380.6 / 1,385.3 / 5,292.3 ms on the original PR. Upstream Hygiene was 0.030 / 0.047 / 0.082 / 0.151 ms, but does not recognize the HTML anchor. These are five-sample medians including file scanning/read and findings; the PR description has the environment and sample ranges. The CI check counts cumulative regex-suffix input, not wall-clock time: 16,418 / 32,802 / 65,570 / 131,106 characters. The guard itself makes four linear The recheck also caught one silent skip, fixed in I also expanded the original validator-only verification to the full Linux suite: 5,272 passed, 51 skipped, with the same two host-dependent failures reproduced again on unchanged upstream. This latest run includes upstream #96 via |
Signed-off-by: Rio Yu <[email protected]>
rng1995
left a comment
There was a problem hiding this comment.
Re-reviewed current head after aa019aa and the merge from main. The follow-up now reports relative URLs that normalize into absolute or drive-relative paths instead of silently skipping them, without performing filesystem lookup; the merge resolution preserves both branches. Focused hygiene/Markdown/quality coverage passes (367 tests) and Ruff is clean. No new blocker found.
Signed-off-by: Rio Yu <[email protected]>
|
Thanks for the re-review. Merged current Rechecked the merged tree: 366 passed, 1 skipped on Windows; 5,343 passed, 51 skipped, 2 failed in the full Linux suite. Both failures reproduce on unchanged All 15 GitHub checks passed on |
Signed-off-by: Christopher Kevin <[email protected]>
chrisknvidia
left a comment
There was a problem hiding this comment.
Re-reviewed current head 3b13a83. The supported-Python compatibility and Quality Score compatibility issues are fixed, all review conversations are resolved, and all fresh hosted checks pass. Approving.
Summary
Closes #108.
Use the existing shared CommonMark parser for Hygiene dead-link checks. This covers reference-style, collapsed, shortcut, HTML-anchor, and Markdown-image destinations without treating code, comments, or non-navigation HTML as links. Local destination normalization is shared with quality scoring, and repeated equivalent destinations produce one finding per document.
The review follow-up keeps scheme classification before percent decoding, preserves invalid UTF-8 bytes without replacement-character aliasing, rejects Windows anchors after dot-segment normalization, contains frontmatter and per-target lookup failures, escapes and bounds diagnostics, and avoids repeated suffix scans for unclosed inline comments, processing instructions, CDATA, and declarations.
Behavior changes
<img src>remains outside scope, matching the old regex.../targets retain their previous lookup behavior; containment is not changed by this PR.Invalid local linkfinding without filesystem lookup; they are not silently skipped. Repeated identical invalid hrefs are reported once per document. Quality scoring retains the shared helper's default behavior.Verification
CHANGELOG.mdResults on the current candidate:
fec0b96. The earlier combined run including upstream fix: scan Markdown headings for PII instead of skipping them #96's Security tests was 566 passed, 1 skipped.fec0b96. Both failures were also reproduced on unchanged upstream5387261: the runtime-discovery test sees the host's/usr/bin/codex, and the legacy bridge-port test cannot bind the already occupied port 18080. No host services or installed tools were changed to work around these tests.The regressions exercise the
run_validationboundary and CLI/Markdown reporting. Five new unsafe-anchor cases failed on the previous published behavior and now produce a finding while preserving the subsequent link check. A dedup regression checks repeated invalid hrefs across three link syntaxes in two documents. A 2,704-case comparison found no changes to the helper's default normalization results. Malformed-frontmatter tests assert that body links are still checked; unexpected lookupRuntimeErrors propagate. Truncation tests cover control characters at the display boundary, distinguishing the CLI's intentional SGR colors from injected control sequences. Their fixed-width console separates the message-escaping check from intentional terminal reflow.Scaling checks cover all four unclosed HTML forms at 8/16/32/64 KiB using the cumulative suffix length passed to the HTML regex rule, not elapsed-time thresholds. The inline-source cache tests also fail under a deliberately stale-cache mutation: all four expose a hidden anchor that must remain suppressed.
Same-host timing
Linux / Intel Core i9-13900K / Python 3.13.13 / markdown-it-py 4.2.0 / PyYAML 6.0.3. Median of five samples after one warm-up per size; upstream samples batch 100 calls to reduce clock noise. The timed boundary is
_check_dead_links, including file enumeration/read, parsing, lookup, and findings. No full test suite ran concurrently.Input:
'<a href="before.md">before</a>' + '<!--' * (kib * 256)in oneguide.md. The repeated-openers payload is 8/16/32/64 KiB, plus the 30-byte anchor prefix.c15ac0f5e73a27aa019aaBoth PR versions preserve the preceding anchor. The upstream regex does not recognize HTML anchors, so its lower timing is not equivalent functionality. All measured calls stayed within a 15-second budget. Revised sample ranges were 9.017–9.192 / 18.928–19.415 / 41.902–42.350 / 100.643–100.906 ms.
The later merges of upstream #96 in
9f3e223and #78 infec0b96resolved changelog-only conflicts by retaining both entries. Neither changed this PR's reviewed source/tests, or the Hygiene/Markdown implementation used for the timing comparison above.The deterministic check measures 16,418 / 32,802 / 65,570 / 131,106 cumulative regex-input characters for the comment fixtures, at most twice the input length. The guard does four fixed-terminator
rfindscans once per inline source (linear input work), then constant-size opener checks. The same bound holds for the tested processing-instruction, CDATA, and declaration families. This bounds the guard/regex-suffix work for these fixtures, not end-to-end parser time or all Markdown inputs.Release Impact
CHANGELOG.md