docs(standards): rebase cross-kind wiki links via MkDocs hook

The standards wiki links to the sibling library reference with ../lib/... paths. Add src/hooks.py and enable it in mkdocs.wiki.yml so those links climb to the repo root and resolve to /standards/lib/... under directory URLs.
This commit is contained in:
2026-10-17 17:22:37 +05:30
parent f2f09cf2c9
commit a1b74e5086
7 changed files with 48 additions and 9 deletions

Binary file not shown.

36
standards/src/hooks.py Normal file
View File

@@ -0,0 +1,36 @@
"""MkDocs hook: rebase cross-kind links to the repository root.
The standards wiki links to the sibling library reference with
source-relative paths such as ``../lib/13_library_registry/``. MkDocs only
rewrites links whose target lives inside ``docs_dir``, so those links are
emitted verbatim and, under ``use_directory_urls``, resolve into
``/standards/wiki/lib/...`` and break.
This hook rewrites ``../lib/``, ``../api/`` and ``../wiki/`` links to climb to
the repository root, so they resolve to ``/<repo>/<kind>/`` regardless of how
deeply the page is nested. It mirrors the ``docforge-linkfix`` MkDocs plugin.
"""
from __future__ import annotations
import re
_CROSS_KIND_LINK = re.compile(r"\]\((?:\.\./)+(lib|api|wiki)/")
def on_page_markdown(markdown, *, page, config, files):
"""Prefix cross-kind links with the depth required to reach the repo root.
Args:
markdown (str): The raw Markdown source of the current page.
page: The page being rendered; its destination URI determines how many
directory levels the output sits below the site root.
config: The active MkDocs configuration (unused).
files: The collection of files in the site (unused).
Returns:
str: The Markdown with cross-kind links rebased to the repo root.
"""
depth = page.file.dest_uri.count("/")
prefix = "../" * (depth + 1)
return _CROSS_KIND_LINK.sub(lambda match: f"]({prefix}{match.group(1)}/", markdown)

View File

@@ -4,6 +4,9 @@ docs_dir: wiki
site_dir: ../wiki
use_directory_urls: true
hooks:
- hooks.py
theme:
name: material
palette:

View File

@@ -671,7 +671,7 @@ port/adapter binding, performed by the composition root at startup.</p>
<li><strong>Spec-first.</strong> The HTTP contract is declared in <code>openapi.yaml</code>; route
handlers are looked up by <code>operationId</code>. There are no decorator routers.</li>
<li><strong>Reuse the libraries.</strong> Orchestration, DI, Mongo repositories, ingestion,
auth, and docs come from internal libraries — see the <a href="../lib/13_library_registry/">Library
auth, and docs come from internal libraries — see the <a href="../../lib/13_library_registry/">Library
Registry</a>.</li>
<li><strong>Explicit state machines.</strong> Long-running work moves through explicit,
durable statuses and can pause for human input.</li>

View File

@@ -579,7 +579,7 @@ copying Tier B template components.</p>
<blockquote>
<p><strong>Doc model:</strong> this page is the human entry point. The deterministic,
machine-facing checklist lives in the reference page
<a href="../lib/01_build_recipe/">Build Recipe</a>, served as <code>docs://modules/build_recipe</code>.</p>
<a href="../../lib/01_build_recipe/">Build Recipe</a>, served as <code>docs://modules/build_recipe</code>.</p>
</blockquote>
<hr />
<h2 id="what-the-agent-needs-from-you">🧾 What the agent needs from you</h2>
@@ -592,7 +592,7 @@ machine-facing checklist lives in the reference page
the families and their input formats (or "none").</li>
<li><strong>Auth needed now?</strong> Default <strong>no</strong>. Auth is deferred (<code>py-jwt</code> primitives
only), and an authless app is just a spec with no <code>security</code> keys — see
<a href="../lib/04_spec_first_routing/#authless-apps">Spec-First Routing → Authless apps</a>.</li>
<a href="../../lib/04_spec_first_routing/#authless-apps">Spec-First Routing → Authless apps</a>.</li>
<li><strong>Integrations.</strong> Mongo, ingestion formats, email, LLM provider.</li>
</ol>
<p>If you can state axes 1 and 2, the rest is mechanical.</p>
@@ -619,9 +619,9 @@ machine-facing checklist lives in the reference page
<hr />
<h2 id="reference">📚 Reference</h2>
<ul>
<li><a href="../lib/01_build_recipe/">Build Recipe</a> — the deterministic checklist</li>
<li><a href="../lib/12_genericity_matrix/">Genericity Matrix</a> — Tier A / B / C</li>
<li><a href="../lib/13_library_registry/">Library Registry</a> — the Tier A catalog</li>
<li><a href="../../lib/01_build_recipe/">Build Recipe</a> — the deterministic checklist</li>
<li><a href="../../lib/12_genericity_matrix/">Genericity Matrix</a> — Tier A / B / C</li>
<li><a href="../../lib/13_library_registry/">Library Registry</a> — the Tier A catalog</li>
<li><a href="../02_components/">App Components</a> — the component model</li>
</ul>
<hr />

View File

@@ -622,10 +622,10 @@
<h1 id="releasing-versioning">Releasing &amp; Versioning</h1>
<p>How to cut a release of any Aetos repository. The rule lives in the reference
page <a href="../lib/11_versioning_and_changelog/">Versioning &amp; Changelog</a>; this is the
page <a href="../../../lib/11_versioning_and_changelog/">Versioning &amp; Changelog</a>; this is the
runbook you follow.</p>
<p>Every repository is one of two Drone shapes — a <strong>PyPI package</strong> or a <strong>Docker
deployment</strong> (<a href="../lib/10_drone_pipelines/">Drone Pipelines</a>). Both release the
deployment</strong> (<a href="../../../lib/10_drone_pipelines/">Drone Pipelines</a>). Both release the
same way: the version bump and changelog promotion go <strong>in the merge request</strong>,
and the tag is created on the merged commit.</p>
<hr />
@@ -750,7 +750,7 @@ outage):</p>
<hr />
<h2 id="related">Related</h2>
<ul>
<li><a href="../01_testing/">Testing &amp; Quality Gates</a> · <a href="../lib/11_versioning_and_changelog/">Versioning &amp; Changelog</a> · <a href="../lib/10_drone_pipelines/">Drone Pipelines</a></li>
<li><a href="../01_testing/">Testing &amp; Quality Gates</a> · <a href="../../../lib/11_versioning_and_changelog/">Versioning &amp; Changelog</a> · <a href="../../../lib/10_drone_pipelines/">Drone Pipelines</a></li>
</ul>

Binary file not shown.