diff --git a/.github/workflows/qualify.yml b/.github/workflows/qualify.yml new file mode 100644 index 0000000..02c2f9c --- /dev/null +++ b/.github/workflows/qualify.yml @@ -0,0 +1,43 @@ +name: Qualify documentation + +on: + pull_request: + branches: [main] + push: + branches: [main] + workflow_dispatch: + +concurrency: + group: docs-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + qualify: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + persist-credentials: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version-file: .nvmrc + cache: npm + - name: Reject a superseded source head + env: + EXPECTED_HEAD: ${{ github.event.pull_request.head.sha || github.sha }} + run: test "$(git rev-parse HEAD)" = "$EXPECTED_HEAD" + - run: npm ci --ignore-scripts + - run: npm run qualify + - name: Preserve qualified static output + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: auths-docs-static-${{ github.event.pull_request.head.sha || github.sha }} + path: dist/client/ + if-no-files-found: error + retention-days: 7 + compression-level: 9 diff --git a/.gitignore b/.gitignore index 8e2987c..2013f90 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ # misc .DS_Store *.pem +*.tsbuildinfo # debug npm-debug.log* diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..e222811 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22.19.0 diff --git a/README.md b/README.md index 9f4e17d..28e2d1c 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,31 @@ -# Auths Documentation Prototype +# Auths Documentation -This repository is the visual and authoring prototype for `docs.auths.dev`. -It deliberately stops before AP-SPEC-040 implementation: no generated SDK -reference, release contract ingestion, cross-repository automation, search -index, or deployment qualification exists yet. +This repository builds the public `docs.auths.dev` experience from free-form +editorial MDX and an immutable, checksum-addressed Auths product snapshot. -The current template proves four things: +The product contract is: -- a concrete design language for Auths documentation; -- a product-led landing page with progressive disclosure; -- MDX as an authoring format for technical guides; and -- synchronized Rust, TypeScript, and Python examples on one semantic page. +- begin with outcomes and five stable verbs; +- progressively disclose protocol and operational depth; +- generate reference facts from installed SDK and runtime artifacts; +- render maintained TypeScript and Python recipes from pinned product source; and +- publish equivalent HTML and canonical Markdown for people and agents. -## Pages +## Information architecture -- `/` — main documentation landing page -- `/guides/protect-rest-effect` — representative multi-language guide +`content-v2/navigation.json` owns the homepage route, the public documentation +routes, top navigation placement, left navigation groups, and page ordering. +The four primary destinations are: + +- `/start` — choose a first workflow and run a maintained quickstart; +- `/guides` — integrate Auths and understand the authority and verification models; +- `/examples` — inspect production-shaped examples by security question; and +- `/reference` — look up the exact SDK, protocol, outcome, and evidence surfaces. + +Conceptual material lives inside Guides rather than in a separate top-level +section. The custom homepage layout reads its copy from the registry-owned +`content-v2/home.json`, which also generates `/index.md` and machine-readable +discovery entries. ## Local development @@ -29,20 +39,25 @@ npm run dev Run the production build and checks: ```bash +npm run docs:build +npm run routes:check +npm run typecheck npm run build npm run lint -npm test +npm run audit:docs ``` -## Prototype decisions +## Architecture decisions Read: - [`docs/TOOLING.md`](docs/TOOLING.md) - [`docs/DESIGN_LANGUAGE.md`](docs/DESIGN_LANGUAGE.md) - -This prototype uses Vinext/Vite for a fast preview and deploy loop while using -MDX for the representative guide. It does not silently replace AP-SPEC-040's -Astro/Starlight implementation decision. Before the full epic work begins, use -this prototype to decide which shell to carry forward; the design tokens, -components, MDX content, and interaction contract are intentionally portable. +- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) +- [`docs/MAINTENANCE.md`](docs/MAINTENANCE.md) + +The site is static-first. Product facts enter only through `product-snapshot/`; +editorial explanations live under `content-v2/`. The site has no production +database, provider credentials, or runtime authority. Client JavaScript is +reserved for search, navigation state, synchronized language selection, and +copy actions. diff --git a/app/[...slug]/page.tsx b/app/[...slug]/page.tsx new file mode 100644 index 0000000..57b9b13 --- /dev/null +++ b/app/[...slug]/page.tsx @@ -0,0 +1,22 @@ +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { DocsShell } from "../components/docs/DocsShell"; +import { docsPage, docsPages } from "../lib/docs-content"; + +export function generateStaticParams() { + return docsPages.map((page) => ({ slug: page.path.slice(1).split("/") })); +} + +export async function generateMetadata({ params }: { params: Promise<{ slug: string[] }> }): Promise { + const { slug } = await params; + const page = docsPage(`/${slug.join("/")}`); + if (!page) return {}; + return { title: page.frontmatter.title, description: page.frontmatter.description, alternates: { canonical: page.path } }; +} + +export default async function Page({ params }: { params: Promise<{ slug: string[] }> }) { + const { slug } = await params; + const page = docsPage(`/${slug.join("/")}`); + if (!page) notFound(); + return ; +} diff --git a/app/components/AuthsLogo.tsx b/app/components/AuthsLogo.tsx new file mode 100644 index 0000000..0e6d345 --- /dev/null +++ b/app/components/AuthsLogo.tsx @@ -0,0 +1,3 @@ +export function AuthsLogo() { + return