İçeriğe geç

ADR-019: Documentation Framework And Content Model

Geliştirme · 0.0.0-dev

Yayın

Doküman
0.0.0-dev
Uygulama
0.0.0

Bu sayfa

Uygulama
0.0.0
  • Status: Accepted
  • Date: 2026-08-18
  • Roadmap task: F1-014
  • Decision owners: documentation and project architecture maintainers

Munderecat needs one documentation product for three distinct audiences:

  • readers who need product and corpus guidance,
  • contributors and maintainers who need technical contracts and runbooks,
  • project auditors who need decisions, provenance and release evidence.

Documentation must evolve with the monorepo without becoming a second copy of the source material. It must build without a database or application server, support Turkish as the initial canonical language, remain ready for additional locales, provide local full-text search and keep raw execution records out of the normal reader experience.

The decision was evaluated against these requirements:

  1. deterministic static production output,
  2. Markdown and selective MDX support,
  3. first-party local search without a hosted service,
  4. accessible navigation, syntax highlighting and dark/light themes,
  5. locale-aware routes and UI,
  6. schema-validated metadata that can be extended by the project,
  7. direct consumption of root docs/ sources without copies or symlinks,
  8. release-versioned documentation without copied authored trees,
  9. an independent build and deployment boundary from apps/web.

apps/docs will use Astro with the Starlight documentation integration. Dependencies and exact versions are selected and locked by F1-015; this ADR selects the architecture, not a floating package version.

Starlight is selected because its default operating model matches the project:

  • pages are prerendered to static HTML by default,
  • Pagefind provides build-time, local full-text search,
  • navigation, code highlighting, dark/light themes and documentation page semantics are built in,
  • root-locale and translated-locale routing are supported,
  • Turkish UI strings are available,
  • docsSchema() can be extended with project metadata,
  • Astro content loaders can read Markdown/MDX from a repository-root content tree and assign deterministic entry IDs.

F1-015 must prove the external-root collection path with a minimal production build before adding real documentation. The intended implementation is one Astro docs collection using Starlight’s docsSchema() and either Astro’s glob() loader or a small project-owned loader. It will read selected paths under repository-root docs/ and map them to Starlight entry IDs. If the installed Starlight version cannot consume that collection contract, F1-015 must stop and revisit this ADR; copying files into apps/docs, symlinking a second tree or silently adding a build-time mirror is not an acceptable fallback.

The canonical deployment product is a provider-neutral static directory:

pnpm --filter @munderecat/docs build
-> apps/docs/dist/

The build must not require PostgreSQL, Supabase, apps/web, a server adapter, credentials or network access to a production service. The output can be served by any static host or CDN. Preview and production hosting provider selection belongs to F1-023 and cannot change this static artifact contract.

Base-path and canonical-site URL configuration may be supplied at build time, but content, navigation and search must remain functional at the root path and under a configured static base path.

The unprefixed documentation routes always represent the current supported documentation release. There is no authored latest copy and no /latest/ segment in canonical URLs.

An immutable historical snapshot is produced by checking out the Git tag or commit recorded by a release manifest and running the same static build with a versioned base path:

current: /user/getting-started/
snapshot: /versions/<docs-release>/user/getting-started/

The snapshot is a release artifact, not a second Markdown source tree on the main branch. It carries the code, docs, schema and data versions from its release manifest and retains its own Pagefind index. A version selector is a static manifest-driven link between deployed artifacts; it does not query a live service. Old snapshots are rebuilt only from their recorded Git object and locked toolchain, never by copying current pages into version directories.

Starlight does not need to own document-version semantics for this model. Astro must support deterministic static builds at the configured base path, while Git and Munderecat release manifests own source identity and retention. F1-022 implements the release badge, selector, snapshot manifest and exact retention policy within this boundary. F1-015 must include a versioned-base-path smoke fixture so that this capability is proved before content migration.

Pagefind is the local search engine. Its index is generated from the static output and shipped with that output; no remote crawler, API key or search server is required.

Every published page will expose audience, locale, doc_id and status as search metadata. F1-018 owns the audience-aware result UI and filters. Raw execution packets, leases and evidence are excluded from the default index. Project summaries may link to those records without indexing their full body.

Pagefind search is a production-build feature, so its smoke test must exercise the built output rather than treating the development server as proof.

There is one source copy. apps/docs renders repository-root content and does not own authored documentation.

Canonical Turkish authored pages use audience-first paths:

docs/user/<relative-path>.md(x)
docs/developer/<relative-path>.md(x)
docs/project/<relative-path>.md(x)

Translations use a separate locale tree while preserving audience and relative path:

docs/i18n/<locale>/user/<relative-path>.md(x)
docs/i18n/<locale>/developer/<relative-path>.md(x)
docs/i18n/<locale>/project/<relative-path>.md(x)

The three content classes have different publication behavior:

Class Purpose Default navigation/search
user Reader workflows and visible product concepts Included
developer Architecture, data, API, pipeline and operations contracts Included in its own tree
project Decisions, provenance, releases and quality records Secondary; selected records only

docs/project/execution/ is an audit registry, not authored page content. Its packet, acceptance, evidence and generated-index files retain their governance schemas and are not forced into the page frontmatter schema. Later project pages can render deterministic summaries from that registry.

Accepted ADRs under docs/project/decisions/ are project records created before the page schema. They must not be rewritten merely to satisfy the docs framework because their hashes may be referenced by accepted evidence. F1-016 will define a read-only adapter or curated index for publishing them. New authored project pages use the normal page schema.

Turkish is the canonical and only mandatory documentation locale for the initial release. Additional translations are welcome but cannot block that release merely because their coverage is incomplete.

Turkish uses unprefixed stable routes:

/user/getting-started/
/developer/architecture/overview/
/project/decisions/

Other locales place the BCP-47 locale before the audience:

/en/user/getting-started/
/en/developer/architecture/overview/

Adding a locale cannot change a Turkish URL or a document’s stable identity. Missing translations are never silently presented as if they were in the selected locale. Any explicit fallback must show its actual locale and fallback state. F1-026 owns the exact doc_id, translation pairing, redirect and collision-validation contract within these boundaries.

F1-016 will implement a schema extending Starlight’s docsSchema(). Every authored page must provide at least:

doc_id: stable-language-independent-id
title: Human-readable title
description: Search and navigation summary
audience: user | developer | project
locale: tr
status: draft | verified | deprecated
owners:
- owner-id
last_verified: YYYY-MM-DD
applies_to:
app: version-or-null
schema: version-or-null
data: version-or-null
source_of_truth: manual | generated

The schema must enforce that physical audience and locale agree with metadata, doc_id is globally unique per locale, translated pages pair through the same doc_id, and verified pages have a valid last_verified value. A generated page must identify its version-controlled source and generator; it cannot use a live production database as its only source.

doc_id is identity, the source path controls maintainership, and the route is a presentation address. These values are related but must not be collapsed into one field. F1-026 defines the permanent ID grammar before translated content is accepted.

Markdown is the default authoring format. MDX is allowed only where an interactive or reusable component provides concrete value. A page must not use MDX merely for layout that Starlight or Markdown already supports.

The first screen is the documentation product, not a marketing landing page. It provides clear Kullanici and Gelistirici entry points. Their sidebar trees remain independent so reader guidance is not mixed with migrations, schema or pipeline details.

Proje is a secondary surface reachable from the developer area. Decisions, provenance, releases and curated quality summaries can be published there; raw execution records remain outside ordinary navigation and search.

Navigation is explicit for top-level information architecture and may be generated within bounded subsections. Filesystem order alone is not a public navigation contract.

  • The docs application remains deployable as static files with no runtime service or secret.
  • Search, locale support, accessible documentation navigation and themes are obtained without building a custom documentation shell.
  • Authored content remains in one visible repository-root tree and is usable outside the application.
  • Turkish routes stay stable when more languages are added.
  • Historical documentation can be retained as immutable static builds without maintaining copied source trees on the active branch.
  • Audience boundaries and searchable metadata support both readers and open source contributors without exposing the execution registry as normal help content.
  • Framework metadata is extended rather than replacing project-owned document identity and provenance.
  • Reading root docs/ through a non-default Starlight collection path requires a small integration proof and collision tests in F1-015/F1-016.
  • Audience-aware Pagefind result controls will require a bounded search UI customization in F1-018.
  • Starlight does not provide the selected release-snapshot policy itself; F1-022 and release automation must build, label and retain versioned static artifacts from recorded Git objects.
  • Existing ADRs need an adapter or index because mutating accepted records to add frontmatter can invalidate historical hashes.
  • Starlight/Astro upgrades must preserve custom loader, route and metadata contracts; lock updates require a docs production-build check.
  • Static output rules out runtime-only documentation features unless they can be expressed as client-side enhancements over generated content.

Fumadocs offers strong React composition, i18n and Orama search, and it can produce static output. Its default model is server-first, while static search requires an explicit exported index/client path. Reusing Next.js solely because apps/web already uses it would also couple two intentionally independent applications to the same runtime model. It was not selected for the initial docs foundation.

Docusaurus provides mature static documentation and i18n. Its first-class search integration is hosted Algolia DocSearch; local search choices are community maintained. That does not satisfy the project’s preference for a first-party, zero-service local search path as directly as Starlight/Pagefind. Its built-in content versioning is useful, but Munderecat’s Git-object snapshot model keeps historical source and release identity framework-independent.

Both can satisfy static output, but navigation, search, locale behavior, accessible documentation components and theme behavior would become project-owned product code. That cost does not create domain value and was rejected.

This would make framework setup conventional but create a second content tree, unclear edit ownership and drift checks for otherwise identical files. It is explicitly rejected.

  • F1-015: locked install, external-root loader spike, DB-free static build and base-path smoke test.
  • F1-016: frontmatter schema, path/metadata agreement and duplicate identity validation.
  • F1-017: independent user/developer entry points and navigation trees.
  • F1-018: Pagefind audience/locale metadata and result filtering.
  • F1-020/F1-021: lint, link, slug, orphan, production build and public Make commands.
  • F1-022: manifest-driven version badge, immutable historical snapshot build, selector and retention policy.
  • F1-023/F1-024: hosting previews, responsive behavior, accessibility and dark/light verification.
  • F1-026: stable doc_id, translations, URLs and redirects.
  • The F1-015 production fixture proves Starlight cannot consume the root docs collection without duplication or unsupported internals.
  • Pagefind cannot provide locale and audience metadata needed by F1-018 without replacing most of Starlight’s search surface.
  • Static output cannot satisfy an accepted documentation requirement.
  • Starlight ceases maintained support for Astro’s current content layer or the required accessibility/i18n features.