Menu

#306 feat(ci): add offline Markdown link checker

closed
nobody
None
2026-08-10
2026-08-09
Anonymous
No

Originally created by: jasperdingg

Pull Request

Slice

  • Repo: doberman-core
  • Feature / Slice: [#175]
  • Plan reference: issue [#175]

What this PR does

  • Adds offline markdown link and anchor checker
  • Skips external urls
  • Rejects paths outside the repo
  • Adds tests and runs the checker in CI

Tests added (run in CI)

  • pytest tests/unit/test_markdown_links.py -q, 7 passed
  • python scripts/check_markdown_links.py, 20 files checked
  • ruff check .
  • ruff format --check .
  • lint-imports

Public-release safety (doberman-core only)

  • [x] Contains nothing from the "not allowed" list: no enterprise/hosted code, no proprietary detection, no customer data, no secrets, no commercial-license code
  • [ ] Core still builds/tests/runs with NO enterprise package installed

Security checklist

  • [x] Fails closed on error / uncertainty
  • [x] No secret, full file, or unredacted prompt logged or committed
  • [x] Any guardrail/learning change is raise-only (no silent loosening)
  • [x] Every BLOCK/AUTH carries reason codes + a human explanation
  • [x] doberman-core does not import doberman_enterprise

Edge cases covered / Deviations from plan / Risks introduced

  • Covers missing files, missing anchors, duplicate headings, external links, fenced code

Related

Tickets: #175
Tickets: #211
Tickets: #298

Discussion

  • Anonymous

    Anonymous - 2026-08-10

    Originally posted by: fu351

    This is the more complete of the two link-checker PRs, and it's ready. It walks the whole tree, so it catches all 23 tracked Markdown files (a curated glob list silently misses the adapters/, examples/, and tools/ READMEs); it handles reference-style links and Setext headings; it normalizes output to forward slashes so the windows-latest CI leg reads consistently; it rejects repo-root escapes (mutation-verified — disabling the check turns a test red); and you moved the README/CONTRIBUTING docs with it. Offline, deterministic, merges clean against main.

    Two follow-ups, neither blocking:

    • A [![badge](img)](target) linked-image gets only its inner image URL checked, never the outer target. This repo's own README has a few (./LICENSE, #roadmap) that resolve fine today, so it's a latent blind spot rather than a live break — worth a line to extract the outer target too.
    • Non-.md local targets (images, assets) skip the existence check by design. That's a reasonable scope choice; a future pass could flag broken asset links as well.

    Nice work — this is the one I'd land for [#175].

     

    Related

    Tickets: #175

  • Anonymous

    Anonymous - 2026-08-10

    Ticket changed by: fu351

    • status: open --> closed
     
  • Anonymous

    Anonymous - 2026-08-10

    Originally posted by: fu351

    Merged — this wraps up [#175], thank you! Full-tree scan, cross-platform paths, and the docs moved with it: the standard done right. Two easy follow-ups whenever: extracting the outer target of [![badge](img)](target) links, and (optional) asset-existence checks. For a fresh one, #211 (add Python 3.13 to the CI matrix, level-6) suits your CI work well — want it? That's two clean test/CI PRs from you today.

     

    Related

    Tickets: #175


Log in to post a comment.