[GH-ISSUE #4264] [Bug] Website verification compares resolved targets against unresolved root aliases #1685

Closed
opened 2026-10-16 21:09:03 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @morluto on GitHub (Oct 15, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4264

Website checker rejects valid links when its root is a path alias

Actual result

The website maintenance check fails on valid intra-site links when the supplied root or site path uses a symlink alias. On macOS, tempfile.TemporaryDirectory() returns paths under /var/..., while Path.resolve() yields /private/var/...; an explicitly symlinked root or site produces the same mismatch on any platform. check_repository_links() and check_site() resolve each target but compare it with the caller's unresolved boundary path using Path.is_relative_to().

This caused four failures in scripts/test-website.py after scripts/website.py check prepared the site. The repository-link test reports an existing ../docs/guide.md as missing. The site-link tests report correct https://rea.tools/... targets as leaving the website, so expected missing-target and missing-fragment diagnostics are absent. The new-page test sees 510 false “reference leaves the website” errors.

Reproduction and controls

Environment: macOS, Python 3.14, repository website venv with pinned requirements. Root's command used DYLD_LIBRARY_PATH=/opt/homebrew/lib and DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib to run scripts/website.py check; the exact test output is in .cache/codebase-audit/website-check.log.

Source-owned disposable probe:

  • check_repository_links(canonical_root) returned []; passing the same directory via its /var/... temporary-directory alias returned website/README.md: missing repository target: ../docs/guide.md.
  • check_site(canonical_site) returned zero errors; passing the same prepared site via an explicit directory symlink returned 31,466 errors, starting with valid canonical links reported as reference leaves the website.

The checker should accept the same valid tree through its canonical path and any directory alias. This is a reproduction through the Python functions, not a browser or published-site issue.

Smallest structural fix

Canonicalize the containment boundary once at each owner entrypoint (root = root.resolve() in check_repository_links() and site = site.resolve() in check_site()) before discovering files or resolving targets. This makes both sides of the containment comparison use one representation while preserving the existing checks that reject references escaping the repository or site. Keep regressions for a canonical input and an explicit symlink alias; do not merely canonicalize the temporary paths in tests, since callers may legitimately invoke the checker through aliases.

GitHub all-state issue searches for “website checker symlink path resolve root”, “verify-website check_site leaves website symlink”, and “website tests temporary directory /var /private” returned no matching issues.

Scope limits

No tracked source or test changes have been made. The full website check generated its normal ignored outputs; the failure is limited to Python path containment under aliased input roots. No website content or publishing behavior was changed.

Originally created by @morluto on GitHub (Oct 15, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4264 # Website checker rejects valid links when its root is a path alias ## Actual result The website maintenance check fails on valid intra-site links when the supplied `root` or `site` path uses a symlink alias. On macOS, `tempfile.TemporaryDirectory()` returns paths under `/var/...`, while `Path.resolve()` yields `/private/var/...`; an explicitly symlinked root or site produces the same mismatch on any platform. `check_repository_links()` and `check_site()` resolve each target but compare it with the caller's unresolved boundary path using `Path.is_relative_to()`. This caused four failures in `scripts/test-website.py` after `scripts/website.py check` prepared the site. The repository-link test reports an existing `../docs/guide.md` as missing. The site-link tests report correct `https://rea.tools/...` targets as leaving the website, so expected missing-target and missing-fragment diagnostics are absent. The new-page test sees 510 false “reference leaves the website” errors. ## Reproduction and controls Environment: macOS, Python 3.14, repository website venv with pinned requirements. Root's command used `DYLD_LIBRARY_PATH=/opt/homebrew/lib` and `DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib` to run `scripts/website.py check`; the exact test output is in `.cache/codebase-audit/website-check.log`. Source-owned disposable probe: - `check_repository_links(canonical_root)` returned `[]`; passing the same directory via its `/var/...` temporary-directory alias returned `website/README.md: missing repository target: ../docs/guide.md`. - `check_site(canonical_site)` returned zero errors; passing the same prepared site via an explicit directory symlink returned 31,466 errors, starting with valid canonical links reported as `reference leaves the website`. The checker should accept the same valid tree through its canonical path and any directory alias. This is a reproduction through the Python functions, not a browser or published-site issue. ## Smallest structural fix Canonicalize the containment boundary once at each owner entrypoint (`root = root.resolve()` in `check_repository_links()` and `site = site.resolve()` in `check_site()`) before discovering files or resolving targets. This makes both sides of the containment comparison use one representation while preserving the existing checks that reject references escaping the repository or site. Keep regressions for a canonical input and an explicit symlink alias; do not merely canonicalize the temporary paths in tests, since callers may legitimately invoke the checker through aliases. ## Duplicate search GitHub all-state issue searches for “website checker symlink path resolve root”, “verify-website check_site leaves website symlink”, and “website tests temporary directory /var /private” returned no matching issues. ## Scope limits No tracked source or test changes have been made. The full website check generated its normal ignored outputs; the failure is limited to Python path containment under aliased input roots. No website content or publishing behavior was changed.
bsakaguchi 2026-10-16 21:09:03 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

@morluto commented on GitHub (Oct 15, 2026):

Follow-up against source baseline 0e1f0bf2d, under the parent lifecycle audit #4227: both canonical-path controls passed while the same trees passed through explicit directory symlinks produced false missing-target and “reference leaves the website” errors. The checker now resolves each repository/site containment boundary once before discovery. Symlink regressions and an escaping-reference negative control pass. The full scripts/website.py check completed successfully; its maintenance suite ran 17 tests successfully. This is a local path-alias handling defect, not a published-site failure.

<!-- gh-comment-id:6202859146 --> @morluto commented on GitHub (Oct 15, 2026): Follow-up against source baseline `0e1f0bf2d`, under the [parent lifecycle audit #4227](https://github.com/morluto/rea/issues/4227): both canonical-path controls passed while the same trees passed through explicit directory symlinks produced false missing-target and “reference leaves the website” errors. The checker now resolves each repository/site containment boundary once before discovery. Symlink regressions and an escaping-reference negative control pass. The full `scripts/website.py check` completed successfully; its maintenance suite ran 17 tests successfully. This is a local path-alias handling defect, not a published-site failure.
Author
Owner

@morluto commented on GitHub (Oct 16, 2026):

Fixed on main in 034293df1. The website verifier resolves repository and generated-site roots before containment checks, preserving symlink aliases without accepting escapes.

Canonical/symlink root and escaping-path controls cover the reported local verifier defect.

Hosted main CI is still pending; this closure is based on the implemented fix and the scoped regression evidence.

<!-- gh-comment-id:6206008276 --> @morluto commented on GitHub (Oct 16, 2026): Fixed on `main` in [034293df1](https://github.com/morluto/rea/commit/034293df14c558a0fff4467fb28099148f9834a5). The website verifier resolves repository and generated-site roots before containment checks, preserving symlink aliases without accepting escapes. Canonical/symlink root and escaping-path controls cover the reported local verifier defect. Hosted main CI is still pending; this closure is based on the implemented fix and the scoped regression evidence.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1685
No description provided.