ADR-0004: Manifest-Backed Site Navigation And Search
- Status: Accepted
- Date: 2026-07-15
- Amended: 2026-08-01 for locale-aware navigation, bounded per-locale search, and rendered-browser validation
- Owners: documentation, tooling
Context
FOnline documentation is published from repository Markdown through GitHub Pages/Jekyll at https://fonline.ru. At adoption, the publication route and AI delivery were source-owned, but the rendered site still presented the basic Slate repository page: readers had no persistent documentation map, integrated search, current-version identity, mobile documentation navigation, or page-local table of contents.
Hand-authored Jekyll menus would duplicate Docs/documentation-manifest.json. Hosted search or a separate site application would add another deployment and availability boundary. Moving all pages or adding front matter only to satisfy a theme would also mix presentation metadata into the canonical technical corpus before the reviewed locale migration began.
Decision
Docs/documentation-manifest.jsonowns site navigation groups and search policy insite_delivery. Navigation entries refer to stable document IDs, never copied titles or handwritten URLs.BuildTools/docs_site.pydeterministically generates:Docs/Site/Data/docs-site.json, consumed by Jekyll/Liquid for navigation, site identity, repository identity, and the rolling source-ref indicator;Docs/Site/Assets/docs-search.jsonfor English andDocs/Site/Assets/docs-search.ru.jsonfor Russian, consumed by the local browser script for locale-scoped static search.
- Main navigation contains every public, current, human-facing top-level document exactly once. Generated reference detail pages stay behind their generated index pages so the sidebar remains scannable.
- Each locale index includes every public, current, human-facing document available in that locale, including generated detail pages. Internal records, placeholders, AI-only maintainer routes, and missing translations are excluded. Russian navigation falls back to the English route only where no current Russian counterpart exists; search results never cross locales.
- Each search artifact stores compact weighted token postings and result metadata, not full document bodies. Titles and headings receive higher weight than body terms; technical identifiers and their camel-case components remain searchable. Pure numeric tokens and terms present in more than 60% of that locale’s documents are omitted because they cannot distinguish results. Search indexes have no byte-size limit; generation includes the complete eligible corpus for each locale.
Docs/Site/Layouts/default.html,Docs/Site/Assets/css/docs.css, andDocs/Site/Assets/js/docs.jsform a thin rendering layer over{{ content }}. They may provide responsive navigation, search, page table of contents, copy controls, source links, and a persisted light/dark preference, but they do not own technical prose.- The interface uses only repository-owned static assets and browser APIs. It has no hosted search, remote JavaScript/CSS dependency, application build, server API, or generated HTML checked into source.
- The visible version indicator reads the Engine version from root
VERSIONand links to the active locale’s changelog. Documentation routing remains the rollingmaster/currentchannel; versioned snapshots remain blocked on the release/tag support decision. - The published FOnline mark is a neutral vector mark authored in
Docs/Site/Assets/images/fonline-mark.svg. It is presentation-only and may be replaced later through a reviewed branding change without affecting document identity. - Markdown must remain readable in the GitHub repository without Jekyll. Navigation/search generation, layout/static contracts, standalone validation, and the GitHub Pages build are required gates in the same change as manifest or rendering updates.
BuildTools/docs_site_artifact.pyvalidates the completedWorkspace/DocumentationSitetree rather than inferring rendered correctness from source. Every current and available locale route, copied static endpoint, canonical URL, language, accessibility landmark/name, search result, and publishable local link is checked before the artifact is retained.- The layout resolves locale pairs by stable document ID, sets the rendered HTML language, labels navigation in the active locale, and exposes an EN/RU switch only when both current routes exist. The browser gate exercises Russian search and both directions of the paired route.
Consequences
Positive
- Readers get a stable, responsive documentation shell without losing clean Markdown or GitHub readability.
- Navigation cannot silently omit a new top-level public document or point at a renamed path.
- Search covers generated technical reference without shipping the whole Markdown corpus to the browser, and each reader downloads only the active locale index.
- The same stable IDs and source ref now drive human navigation, static search, and AI delivery.
- The site remains deployable by the existing GitHub Pages action and custom domain.
Costs
- Adding, translating, or reclassifying public documentation may require assigning its stable ID to a navigation group and regenerating both locale indexes, routes, navigation, localization status, and AI artifacts.
- Client-side search is current-revision document search, not a versioned symbol service or semantic retrieval system.
- Layout changes require both source-level interaction tests and an inspected Jekyll artifact because local static tests cannot prove Liquid rendering.
- Unmigrated flat English paths remain visible during the locale-tree migration. Reviewed migration groups prove canonical EN/RU pages, stable-ID switching, Russian search, and durable legacy pointer routes; ADR-0006, localization status, and the generated route catalog own the current coverage and remaining paths.
Rejected alternatives
- Theme-owned front matter on every page: rejected because it duplicates titles/order and couples technical Markdown to one theme.
- Hosted search: rejected because it adds credentials, indexing delay, privacy, and service availability to static documentation.
- A hand-maintained JavaScript document list: rejected because it would drift from the manifest and AI catalog.
- Full Markdown bodies in the search JSON: rejected because it duplicates the corpus in a browser payload and grows poorly with generated reference.
- A Node documentation application: rejected by ADR-0001; GitHub Pages/Jekyll remains the publisher.
Verification
python BuildTools/tests/test_docs_site.pypython BuildTools/tests/test_docs_site_layout.pypython BuildTools/tests/test_docs_site_artifact.pypython BuildTools/tests/test_docs_browser.pypython BuildTools/docs_site.py --checkpython BuildTools/docs_site_artifact.py --site-dir Workspace/DocumentationSitenpm --prefix BuildTools/docs-browser run auditpython BuildTools/tests/test_docs_validate.pypython BuildTools/docs_validate.py- GitHub Actions
Build documentation siteartifact inspection at desktop and mobile widths