Skip to content

Make check reject Sources links to hidden paths - #321

Merged
Deicyde merged 1 commit into
mainfrom
fix/check-hidden-source-targets
Oct 16, 2026
Merged

Deicyde merged 1 commit into
mainfrom
fix/check-hidden-source-targets

Conversation

@Deicyde

@Deicyde Deicyde commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Closes #304.

Problem

Render omits every blueprint path with a part starting with ., but autoform check tested a ## Sources target against the real vault, so a link to a committed hidden file such as blueprint/.drafts/notes.md passed. Outside sources/, render then rewrote the link to a page it never writes, and mkdocs build --strict in the Pages workflow failed on the chapter page that absorbed the article. autoform audit reads the real vault too, so nothing named the link before MkDocs did. The Roadmap and Formalize skills already say never to link a hidden implementation note from an article.

Change

  • local_target_issue reports a target as hidden-<label>-target when the path the link spells, once its .. steps are applied, has a part below the blueprint starting with . (render's _is_hidden test). Render resolves links in a copy of the vault that has neither hidden paths nor symbolic links, so that is the path it publishes: ../.x/../sources/paper.md passes, and ../.link/paper.md, with .link a symlink to sources, fails although it reaches a published file. The issue suggested judging the resolved path; the two differ only through a symbolic link. A hidden folder above the blueprint does not count, and a hidden page may link to a hidden path, since render publishes neither.
  • check rejects hidden-source-target, naming the article and the link: error: result: source target names a hidden path, which render omits: '../.drafts/notes.md'.
  • Because the rule lives in local_target_issue, audit reports every Sources link that check rejects, as in Make check reject Sources links that name no file in the blueprint #287, and its coverage scan reports hidden-coverage-target. Render already refused such a link in DECOMPOSED evidence, since its copy of the vault holds no hidden file; its message now says the target is hidden, and the audit's coverage contract check, which reads the real vault, now refuses the link too.
  • Every hidden target is rejected, including one under sources/, as the issue recommends. Render is unchanged. Whether a hidden target under sources/ should fail is still open; see below.
  • The Validation section of the CLI reference describes the new rule.

A hidden note under sources/

On main, an article that cites a committed hidden note such as ../sources/.private/paper.md passes check, and in CI render links the note to the repository at the verified commit, where the file exists, so the published link works. With this change, check exits 1 on that link. Both generated workflows run check before render or the Lean build, so such a project stops publishing and every verify run fails until the note moves out of the hidden folder. That is the kind of break #325 undid: it made check warn and keep its exit code for a Sources link that work and search leave out, because Autoform's tools must not break a codebase.

The maintainer has not decided yet whether check should fail on a hidden target under sources/. The review on #326 asks the same question from render's side, so the two are to be decided together:

Tests

  • test_check_rejects_sources_links_that_name_no_file_in_the_blueprint now also checks that ../.drafts/notes.md and ../sources/.private/paper.md fail although both files exist, and that ../.x/../sources/paper.md passes.
  • test_audit_validates_local_source_links_without_network_access now also expects hidden-source-target for ../../.drafts/notes.md.
  • test_local_targets_are_resolved_against_the_boundary covers the coverage label and a hidden page's link to its own heading, which passes. The new test_a_link_through_a_hidden_symlink_is_hidden covers a link through a hidden directory symlink, in a vault that itself sits inside a hidden folder.

The test suite was not run locally; CI runs it. Called directly, outside pytest, these four tests pass on this commit, and each fails with main's local_target_issue at d1ad2fb. ruff check autoform_cli servers tests passes.

Landing

Rebased onto main at d1ad2fb and merges cleanly. #337, merged into main after the last rebase, conflicted in one hunk of markdown.py: the rebase keeps this PR's hidden-target check right after the escape check and follows it with #337's if not os.path.isfile(candidate):, without the try.

Checked with git merge-tree --write-tree, merging each of these PR heads into this branch and into main: #213, #214, #299, #320, #322, #324, #326, #327, #328, #329, #333, #334, #339 and #340 merge cleanly into both; #90, #195, #215, #216, #217, #219 and #284 conflict with main, with the same conflict blocks with and without this PR. #320 makes the graph read Sources links with a code-only label or a reference, which then reach this rule through node.sources with no further change.

Under (a) this PR lands after #326; under (b) no order is needed.

@Deicyde

Deicyde commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Review at 4e55814

Verdict: Request changes. check now rejects a ## Sources link whose target below the blueprint is hidden, and audit reports it too through the shared local_target_issue, so a link to a committed .drafts/notes.md fails check, naming the article, instead of failing mkdocs build --strict on the chapter page. Outside sources/ this matches #287, since render publishes such a link to a page it never writes. Under sources/ it fails a project whose link works in CI today, the pattern #325 reverses, and the body neither weighs that against #325 nor lists #325's conflicts; the README also misdescribes one tested case.

Fixes before merge

  1. Weigh Let work and search omit what they can't represent, and have check warn #325 in the body. On main, a committed hidden note under sources/ that an article cites passes check, and in CI, render links it to the repository at the verified commit (autoform_cli/render.py:2063-2064), where the file exists, so the published link works (confirmed by trace). With this PR, check exits 1 on that link (tests/test_graph.py:564-569). Both generated workflows run check before render or the Lean build, so the project stops publishing and every verify run fails. Record the outcome of the decision below under Change. In the body's Landing section, replace "every open PR head" with the PRs actually checked and add Let work and search omit what they can't represent, and have check warn #325, as in Landing below.
  2. The README says "as written" (autoform_cli/README.md:972-974). The check test expects ../.x/../sources/paper.md to pass (tests/test_graph.py:550), although its text contains .x, and check: a Sources link to a hidden file passes, then fails mkdocs build --strict #304 asked for the resolved path to be judged, not the link text. Suggested wording: "So does a target whose path below the blueprint has a part starting with . once its .. steps are applied, before or after symbolic links resolve, because render omits hidden files and directories." If the resolved-path half goes (first Optional item), drop "before or after symbolic links resolve".

Optional

  • autoform_cli/markdown.py:646-654: the resolved path adds a rejection only for a link through a symlink whose own path is visible. Render refuses such a symlink inside the blueprint (autoform_cli/render.py:678) and keeps only the text of a link through one outside it. Judging the spelled path alone would remove the second candidate, the "or resolves to" wording, and the visible-symlink case at tests/test_markdown.py:424 and :434, without letting a broken link through.
  • check loads articles in hidden roadmap folders, which render omits (autoform_cli/graph.py:288). Such an article citing a sibling hidden file now fails check although render publishes neither file (confirmed by trace). This is rare; a follow-up issue on that loading fits better than a special case here.
  • autoform_cli/markdown.py:648 copies render's _is_hidden (autoform_cli/render.py:708). Render already imports from markdown.py, so the predicate can live there once. The summary line at autoform_cli/markdown.py:613 still describes only links that do not resolve.
  • tests/test_audit.py:518 repeats the check test's three links through the same function. Only its vault inside a hidden folder is new, and that case fits in the tests/test_markdown.py test.

Landing

Decision for the maintainer

This PR came from the same PR swarm that reviewed it, so this is the author's review, not an independent one. It was a static review: no tests were run locally. CI at this head: all 7 checks pass, including the real-Lean jobs.

Posted by PR swarm: PR Swarm Lead

@Deicyde

Deicyde commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Review changes addressed at e485c30

Still open for you: whether check should reject a hidden note under sources/ or let it keep working with a warning. #326's review asks the same question from render's side, so the two are best decided together.

CI is running on this head.

Posted by PR swarm: PR Swarm Lead

Render omits every blueprint path with a part starting with ".", but
check tested a Sources target against the real vault, so a link to a
committed hidden file such as .drafts/notes.md passed. Render then
wrote the link to a page it never publishes, and the strict MkDocs
build in the Pages workflow failed on the chapter page that absorbed
the article. Audit reads the real vault too, so it reported nothing.

local_target_issue now reports a target as hidden-<label>-target when
the path the link spells, after its ".." steps, has a hidden part below
the blueprint, and check rejects hidden-source-target with an error
naming the article and the link. Render resolves links in a copy of the
vault with no hidden paths or symbolic links, so that is the path it
publishes: ../.x/../sources/paper.md still passes, and
../.link/paper.md, with .link a symlink to sources, fails although it
reaches a published file. A hidden page may link to a hidden path,
since render publishes neither.

Because the rule lives in local_target_issue, audit reports every link
that check rejects, and audit's coverage scan reports
hidden-coverage-target too. Render already refused such a link in
decomposition evidence, since its copy of the vault holds no hidden
file; it now says the target is hidden, and audit's coverage contract
check, which reads the real vault, refuses the link as well.

Closes #304.
@Deicyde
Deicyde force-pushed the fix/check-hidden-source-targets branch from e485c30 to 46d90b3 Compare October 15, 2026 22:30
@Deicyde

Deicyde commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up review at 46d90b3

Verdict: Ready to merge. This pass rechecked the last round's fixes and the whole diff against main. check and audit now report a link as hidden only when a page render publishes names a hidden path once the link's .. steps are applied, which is the path render writes, so links on hidden pages, a vault inside a hidden folder, and ../.x/../sources/paper.md all pass as on main. The one blocker, a conflict with #337 after main merged it, is resolved: the branch is rebased onto main at d1ad2fb.

Changed in this pass

  • Rebased onto main at d1ad2fb, after Report malformed Sources and dependency links instead of crashing #337. In local_target_issue the hidden-target block now sits right after the escape check and is followed by Report malformed Sources and dependency links instead of crashing #337's if not os.path.isfile(candidate):, which replaces this branch's try/is_file block.
  • local_target_issue judges only the path the link spells (autoform_cli/markdown.py:653-658). The resolved-path half only added two rejections: a visible symlink to a hidden file, which render's capture refuses anyway, and a link out through a symlink outside the blueprint, which render publishes as plain text.
  • A link on a hidden page is not reported as hidden: a hidden page's link to its own heading failed check, though render publishes neither (tests/test_markdown.py:408-409).
  • The message now reads "names a hidden path, which render omits", and the local_target_issue summary mentions hidden paths.
  • The symlink test now puts the vault inside a hidden folder (tests/test_markdown.py:414), and the separate audit test became one more link in test_audit_validates_local_source_links_without_network_access (tests/test_audit.py:464-491).
  • README (autoform_cli/README.md:973-976): the new sentence no longer reflows the rest of the paragraph, and it limits the exemption to this rule ("unless the article citing it is hidden too").
  • The body and commit message now describe the spelled-path rule and the current merge results.

Decision for the maintainer

This PR came from the same PR swarm that reviewed it, so this is the author's review, not an independent one. No tests ran under pytest locally. After the rebase, the changed check, Markdown and audit tests and #337's two new audit tests were called directly on this head and pass, and ruff check passes. CI at this head: all 7 checks pass, including the real-Lean jobs.

Posted by PR swarm: PR Swarm Lead

@Deicyde
Deicyde marked this pull request as ready for review October 16, 2026 08:47
@Deicyde
Deicyde merged commit a84b391 into main Oct 16, 2026
7 checks passed
@Deicyde
Deicyde deleted the fix/check-hidden-source-targets branch October 16, 2026 08:48
Deicyde added a commit that referenced this pull request Oct 17, 2026
Main brings #344, #320 and #321. graph.py conflicted: #320 moved link
reading into markdown.link_targets with page-wide reference definitions
and deleted _LINK and _INLINE_CODE, so the resolution takes main's
reader and keeps this branch's _MARKDOWN_LINK_TEXT and _HTML_TAG, which
only the article summary uses. Nothing outside the conflict needed a
change: no caller here uses the capture defaults or the
TreeCaptureLimitError attributes #344 deleted, coverage.py's
link_targets calls keep working with the new optional references
argument, and audit reports #321's hidden-source-target code as it
reports every other source issue.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

check: a Sources link to a hidden file passes, then fails mkdocs build --strict

1 participant