Repository navigation
docs: one canonical URL per page, robots.txt, a sitemap and an honest version label (#380, part b) - #394
Merged
Conversation
… version label, with their self-test (#380, part b) Part b of #380 (EN-94), split by ENGINE-TOP and L6; part a (the theme: the 404 page, per-page descriptions and the product link) lands first. cdocs.pineforge.dev is indexed twice per page (/page and /page.html), has no robots.txt or sitemap, and shows a git-describe string as its version. This part is the build, its output and its test: - docs/seo_postprocess.py runs after Doxygen and adds one rel=canonical per page (https://cdocs.pineforge.dev/<page>, the landing page as the site root) and rewrites relative page links from X.html to X (index.html to ./, anchors kept). Absolute, mailto, protocol-relative, root-relative, nested and non-page links, scripts, comments and every non-page file are left alone; a second pass changes nothing. It sets one meta description per page, built from the page title (the landing page gets one sentence condensed from docs/pages/index.md), and generates sitemap.xml from the built pages (sorted, canonical URLs, no 404, no clock data). - docs/_theme/robots.txt (allow all, names the sitemap) is copied to the site root through HTML_EXTRA_FILES in docs/Doxyfile; it lands here because the sitemap it names is generated by this part. - docs/build.sh calls the post-process after Doxygen and sets the version label to the tag name only for a clean checkout of an exact tag and to the word "unreleased" otherwise, so a git-describe string never reaches the site again. `docs/build.sh --self-test-seo` runs the real script on a synthetic site and asserts the output byte for byte, the sitemap URL set, untouched assets, idempotence, failure on empty input, and the version-label rule. - tests/CMakeLists.txt registers it as the CTest row test_docs_seo at the end of the file, so no earlier line moves (the private fixture read evidence pins CMake lines by number). - docs/build.sh stays a proof-read file and docs/seo_postprocess.py joins it, so scripts/ci_docs_only.py (PROOF_READS) and scripts/test_ci_docs_only.py list both, and docs/ci.md says so: five files a proof job reads. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The self-test of docs/seo_postprocess.py, `bash docs/build.sh --self-test-seo`, ran as the CTest row test_docs_seo. A CMake row makes a documentation change look like an engine change. The docs workflow's build job now runs the same command, unchanged, before the real site build, on every pull request, push to main or a v* tag, and manual dispatch. It needs no CMake configure and no C++ build, and a failing self-test stops the job. The CMake row and its comment are removed from tests/CMakeLists.txt, so no earlier line of that file moves. The sentences that named the CTest row (docs/build.sh header, docs/ci.md, and the two PROOF_READS reasons in scripts/ci_docs_only.py) now name the workflow step. Neither the self-test body nor docs/seo_postprocess.py changes. This replaces, on purpose, sentences that dc77b26 added to docs/ci.md and scripts/ci_docs_only.py: the ones saying `docs/build.sh`, whose self-tests are `test_docs_doxygen_retry` and `test_docs_seo`; and `docs/seo_postprocess.py`, which `test_docs_seo` executes on synthetic pages. It also rewrites the older docs/ci.md sentence from 133f571, "`docs.yml` builds the Doxygen site on every pull request and push, as before", which now also says that the build job runs the self-test first. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
luisleo526
added a commit
that referenced
this pull request
Oct 17, 2026
* docs: the 1.6.0 release (changelog, current pair, HPO note) Prepare the final 1.6.0 release documentation dated 2026-10-17, paired with pineforge-codegen 1.6.0 and the matching pineforge-hpo release for selected-window contract revision 1.3. CHANGELOG.md adds the 1.6.0 — 2026-10-17 entry above 1.6.0-rc.1 — 2026-10-14, carrying forward the release-candidate entry's substance and naming the six documentation and test-only changes merged since v1.6.0-rc.1 (#390, #393, #394, #395, #396, #397). README.md updates the current-release block and the codegen command-block pointer to 1.6.0 and adds the v1.6.0 bullet to the Releases section. The current-release block's 1.5.0 sentence from 4c78f39 ("The release notes cover recorded outputs, the call-scoped report rule and the test inputs' move to a private repository") is replaced on purpose by the 1.6.0 sentence that lists what 1.6.0 covers; that 1.5.0 summary stays in the Releases list (the v1.5.0 bullet) and in CHANGELOG.md's 1.5.0 entry. docs/pages/public-contract.md adds the 1.6.0 paragraph after the 1.5.0 paragraph and updates the same-version pairing line to 1.6.0. * docs: 1.6.0 notes review fixes (HPO pairing line, follow-up figures, value-ownership wording) The paired-HPO line no longer claims HPO support for selected-window revision 1.3; HPO 1.6.0 does not implement selected windows (docs/return-stats.md:9 in pineforge-hpo). The landed follow-ups #396/#397 are said to be checked against their own deliberate bugs, and the figures remain the candidate's. README.md and docker/README.md replace "complete value ownership with" by "value ownership through", the wording of the 1.6.0-rc.1 changelog entry, since no completeness proof was run. The changelog's no-code-change sentence names the docker/README.md rewording. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> --------- Co-authored-by: HaoLiangWen <[email protected]> Co-authored-by: CORE-TOP <[email protected]> Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
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.
Part B of #380, on main a871161 (after #390, part A, and #393). It carries the docs build's SEO post-processing and the docs-only CI check:
docs/build.sh,docs/seo_postprocess.py(new),docs/_theme/robots.txt(new), the robots line indocs/Doxyfile,docs/ci.md,scripts/ci_docs_only.pywith its test, and a new CTest rowtest_docs_seointests/CMakeLists.txt. Because it changes build and CI scripts and adds a CTest row, it is not a documentation-only change and is verified with the full set of steps. The description below covers the whole of #380.cdocs.pineforge.devis indexed twice per page (/pageand/page.html), has no robots.txt or sitemap, carries one meta description on every page, shows a git-describe string as its version (v1.5.0-rc.1-7-g42fa1d4b), and links nowhere to the product site. This fixes what the repository can fix (EN-94, items C1-C5).What changes
docs/_theme/footer.html: every page footer links https://pineforge.dev (both footer branches).docs/seo_postprocess.py(standard library only; called bydocs/build.shright after Doxygen): adds onerel="canonical"per page (https://cdocs.pineforge.dev/<page>, the landing page as the site root) and rewrites relative page links fromX.htmltoX(index.htmlto./, anchors kept). Absolute,mailto:, protocol-relative, root-relative, nested and non-page links, scripts, comments and every non-page file are left alone. Running it twice changes nothing. All pages are validated before any is written; an empty or missing site fails the build.docs/_theme/robots.txt(allow all, names the sitemap) anddocs/_theme/404.htmlare copied to the site root throughHTML_EXTRA_FILES(docs/Doxyfile);sitemap.xmlis generated from the built pages (sorted, canonical URLs, no 404, no clock data).404.htmlis a plain static page (absolute stylesheet links, no scripts) and is left untouched by the post-processing.docs/_theme/header.html: the meta description is built from each page's title; the landing page gets one sentence taken fromdocs/pages/index.md(the C++17 engine in two layers: a kernel that knows nothing about PineScript or TradingView, and the Pine adapter).docs/build.sh: the version label is the tag name only for a clean checkout of an exact tag, and the wordunreleasedotherwise.Please read: C5 (stated)
mainis already past thev1.5.0tag, so the deployed site will readunreleasedfrom the first deploy until the next tag is cut. A build of a tag shows that tag.Please read: C3 needs a host-side check (not part of this PR; for the site owners)
Today every unknown path on
cdocs.pineforge.devanswers 200 with the home page (measured 10-12:/robots.txt,/sitemap.xml,/nonexistent-xyzall 200text/html). Nothing in this repository produces that; it is host-side configuration of the Cloudflare Pages projectpineforge-docs(or whatever fronts the domain), and this PR does not touch Cloudflare. Real files are served correctly (/custom.css200text/css), sorobots.txtandsitemap.xmlwill be served as real files after the deploy. For/nonexistent-xyzthe decider iscurl -s -o /dev/null -w '%{http_code}\n' https://cdocs.pineforge.dev/nonexistent-xyz:200 means the host still rewrites unknown paths to
/: the change is then to turn off the single-page-app / not-found fallback on the Pages project (in the site owner's Cloudflare account) so the root404.htmlis served with status 404. 404 means done.Notes for the reviewer
sitemap.xmlhas 1142 URLs (well under the 50,000 limit). The ~70 URLs seen in Google's index are a subset.docs/build.shis a proof-read file, so this PR takes the full CI path (not the documentation-only path).scripts/ci_docs_only.py,scripts/test_ci_docs_only.pyanddocs/ci.mdlistdocs/seo_postprocess.pynext to it.docs/ci.mdwords changed: "four files a proof job reads" -> "five files" (two places) and thedocs/build.shsentence now namestest_docs_seobesidestest_docs_doxygen_retry. If this PR is squash-merged, build the squash body from the two commit messages so those namings stay.0e7a69f7is the change as reviewed;9827eaadmoves thetest_docs_seoregistration to the END oftests/CMakeLists.txt, becausetests/private_fixture_reads.evidencepins CMake lines by number and a registration in the middle moved a pinned line (the first lab run failed exactlytest_private_fixture_readsandtest_private_fixture_reads_controls).bash docs/build.sh --self-test-seo, CTest rowtest_docs_seo) runs the real script on a synthetic site and compares the output byte for byte: canonical per page, rewritten and untouched links, escaped descriptions, sitemap URL set, untouched assets, a second pass identical, failure on empty input, the version rule.HTML_EXTRA_FILESlines) if that lands first.Verification (lab remote, no tests on the Mac)
rj-20261012t195837-b0760d(commit 0e7a69f): preflight passed (49 stages, 0 advisory); docs passed (exit 0, Doxygen warnings 0,==> SEO post-processing: 1143 pages and sitemap.xml). Release, debug, sanitizers, kernel: 2 failures each,test_private_fixture_reads*, fixed by 9827eaa as above.rj-20261012t205443-8ec24a(commit 9827eaa, from a worktree of the primary checkout soabi-prior-fetchhas its remote):ci_verify releasepassed, 911 of 911 tests, 38 stages, 0 failures, includingtest_docs_seo,test_docs_doxygen_retryandtest_private_fixture_reads.rj-20261012t204300-5f005c(commit 9827eaa): debug exit 0, kernel exit 0; sanitizers: see the PR conversation for the final line.🤖 Generated with Claude Code