Repository navigation
Conversation
docs/public/conf.py keeps every link into this repository out of the Sphinx link check and says local checks cover those links, but no check did. A public page could link a blob or tree URL to a path that does not exist, and both docs-local and docs-links passed. tools/public_docs_links.py finds links under the prefixes that linkcheck_ignore skips (github.com/OpenRAE/rae and the former RAESystem owner) that use the blob or tree route on main, dev or HEAD. It resolves each path, percent-decoded and without its query string, fragment or trailing slash, against the files git ls-files lists. A blob link must name a tracked file and a tree link a directory that holds one. Other refs, other repositories and other repository pages are skipped. A failure names the page, the line and the URL, and the check fails closed when git cannot list the tracked files. tools/check_public_docs.py runs the check with its other source checks, so it runs in the docs lane's existing "public source boundary" stage. The conf.py comment now says what the local check covers. Every such link in docs/public resolves, so no page changes.
…heck SonarCloud's python:S1142 allows three returns per function, and _link_problem had four: one for a link on a ref the check skips and one for a link that resolves. Both mean the link has no problem, so one condition now covers them. The check reads the path before it tests the ref, which cannot fail: REPOSITORY_LINK only matches the blob and tree routes, so ROUTE_KINDS has the route. Behavior is unchanged.
doublewhy
force-pushed
the
1494-public-docs-github-links
branch
from
October 11, 2026 23:35
e801413 to
d7e8db2
Compare
doublewhy
marked this pull request as ready for review
October 12, 2026 00:11
9 of 11 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
docs/public/conf.pykeeps every link into this repository out of the Sphinx link check (linkcheck_ignore). Its comment said those links "are covered by local policy and schema checks", but no check covered them.tools/check_public_docs.pyaccepts any target that contains://, so a public page could link ablobortreeURL to a path that does not exist, and bothnox -s docs-localandnox -s docs-linksstill passed (#1494).This PR adds that check.
tools/public_docs_links.pyfinds the links that use theblobortreeroute onmain,devorHEADunder the prefixeslinkcheck_ignoreskips:https://github.com/OpenRAE/rae/and the former ownerRAESystem. It looks each path up in the filesgit ls-files -zlists. Abloblink must name a tracked file, and atreelink must name a directory that holds one.tools/check_public_docs.pyruns it with its other source checks, so it runs at the docs lane's existing "docs / public source boundary" stage. No job, session or workflow changes. All 33 such links indocs/publicresolve atdeva4357f9a, so no page changes.Requirement UIDs
Related Issues
Closes #1494
ADR Impact
Changes
tools/public_docs_links.py(new, 102 lines):https://github.com/OpenRAE/rae/orhttps://github.com/RAESystem/rae/followed byblob/ortree/. The check reads every line of each.mdand.rstpage underdocs/public, code included, so it errs toward false positives, as the directive scan intools/public_docs_markup.pydoes. A URL ends at whitespace or at the markup around it, and trailing sentence punctuation is dropped.main,devandHEADare checked. Those branches carry this tree:devtakes it when the change merges, andmain(HEAD, the default branch) at the next release. Commit SHAs, tags and other branches can name content that the checkout lacks, so the check skips them.git ls-files -z. Git's list matches case exactly, as GitHub does (blob/main/readme.mdreturns 404), and it leaves out untracked files such as the ignored/research/corpus. A link whose route names the other kind of path fails, and the message names the route to use. GitHub serves such a link only through a 301 redirect, for exampleblob/main/specstotree/main/specs. As Public docs checks do not verify in-repo GitHub links #1494's Chosen Architecture specifies, fragments are not checked against headings or line numbers.[public-docs-repository-link] docs/public/<page>:<line>: <url> .... The check fails closed when git cannot list the tracked files._link_problemreturnsNonefrom one condition for both links without a problem: a link on a ref the check skips and a link that resolves. That keeps it at three returns, the most SonarCloud'spython:S1142allows. Therefactor(docs)commit made this change after the first head failedsonar(see CI below), and it changes no behavior. The function now reads the path before it tests the ref, and that read cannot raise, becauseREPOSITORY_LINKonly matches theblobandtreeroutes thatROUTE_KINDSmaps.tools/check_public_docs.py(+5 lines, now 491):main()reads the public pages with the existing_source_pathsand_bounded_texthelpers and adds the link failures to the source failures it always reports.docs/public/conf.py: the comment abovelinkcheck_ignorenow names the local check, and says that links to issues, pull requests and other repository pages stay unchecked, the scope Public docs checks do not verify in-repo GitHub links #1494 sets.linkcheck_ignoreitself is unchanged, andtest_public_docs_linkcheck_is_bounded_serialized_and_skips_own_repositorystill pins it.implementations/python/tests/test_issue_1494_public_docs_github_links.py(new):main, a missing directory ondev, a wrong-case path onHEAD, a missing path under the former owner, a percent-encoded missing path, a URL in a code span, a URL that appears twice on a line (reported once), and both wrong-route cases.http://, another host and a relative link.check_public_docs.main()exits 1 and reports a dead link atdocs/public/quickstart.md:4with its URL, and exits 0 when the page has only a live link.docs/publicis reported once, and the link check does not run.Test Plan
uv run --project implementations/python --frozen --all-extras python -m pytest implementations/python/tests/test_issue_1494_public_docs_github_links.py -qpassed (30 passed, 4 deselected). With-m integration, 4 passed.-m fuzzselects none of its tests. Every result in this section is from headd7e8db23, rebased ontodeva4357f9a. These checks show that the tests catch the defect and its parts:tools/check_public_docs.pyrestored toorigin/devand the new module kept, the dead-link case oftest_checker_reports_dead_links_by_page_line_and_urlfails, becausemain()returns 0 instead of 1.is_dir()guard removed from the newmain()lines, the missing-root test fails, because the link check adds acannot listfailure.HEADremoved from the checked refs, orRAESystemremoved from the pattern, the matching failing-link case fails._link_problem's combined condition, the tag, commit and branch cases oftest_links_outside_the_checked_scope_are_ignoredfail.Under these tests,
tools/public_docs_links.pyhas 100% line and branch coverage, and the newmain()lines are covered.test_public_docs_policy.py,test_issue_954_docs_publication_boundary.pyandtest_verification_plan.pypassed: 90 tests by default and 32 with-m integration.On the repository at this head,
python tools/check_public_docs.pyexits 0 after it scans 24 pages and finds 33 links to check. Withdocs/public/backends.md:19edited totree/main/contracts/schemas/backend-manifests(since reverted), it exits 1 and prints:Nine other open PRs touch
docs/public: #1431, #1436, #1437, #1444, #1449, #1463, #1465, #1470 and #1492. The check finds no failingblobortreelink in any of their heads, or in each head merged with this branch (git merge-tree --write-tree), so it breaks none of them today.nox -s verify-fast-feedback -- --base-rev origin/dev(every stage that ran passed; the YAML and JSON syntax stages had no files to check, and requirement governance was skipped),nox -s lint,make policyandnox -s docs-localpassed. Indocs-local, every stage passed: public source boundary, Vale, executable quickstart, Sphinx HTML and public output inventory.tools/check_specification_coverage.pyandtools/check_formal_semantic_validation.pypassed. None of the changed files is in the research-evidence implementation digest, among the 11tools/files pinned byspecs/formal/participant-semantics/participant-opacity-proof-evidence.json, or undertools/specification_coverage/.Ground Control Checks
make policypassed. Requirement governance is skipped because the branch carries no requirement UID and no scope file. The dead-linkmain()case fails withtools/check_public_docs.pyatorigin/dev, as described in the Test Plan.Traceability
tools/public_docs_links.py,tools/check_public_docs.py,docs/public/conf.pyimplementations/python/tests/test_issue_1494_public_docs_github_links.pylinkcheck_ignoreindocs/public/conf.py(lines 56-59 atdeva4357f9a)Checklist
linkcheck_ignoreand the docs lane's stages are unchanged, and the check only adds failures.cidoes not cut a release.tools/check_public_docs.pystays under SonarCloud's 500-line file limit (python:S104) at 491 lines._link_problemhas three returns (python:S1142), and thesonarjob of CI run 38184864922 passed.Documentation
docs/public/conf.py.docs/public, because all 33blobandtreelinks resolve.CI
d7e8db23(rebased ontodeva4357f9a): all 32 reported checks pass, including the 14 required ones.Docs / deployis skipped because it runs only onmain. Runs: CI 38184864922, whosesonarjob passed with the SonarCloud gate at OK and no new issues; Docs 38184864673; Bootstrap qualification 38184864683; CodeQL 38184862787; PR Body Policy 38184864681; PR Title Lint 38184864663.e8014138failed onlysonar(run 38164587590), on one new issue:python:S1142attools/public_docs_links.py:91, where_link_problemhad four returns and three are allowed. Therefactor(docs)commit fixes the code itself, with no suppression, as Changes describes.