How this site is built
This site is a working demonstration of content operations, so the pipeline deserves its own page. Everything below is inspectable in the repository.
The stack
- Docusaurus in docs-only mode. Content is Markdown and MDX; the sidebar is a deliberate, hand-ordered map rather than a generated file tree.
- GitHub for hosting, review, and history. Changes land through pull requests, including my own.
- GitHub Actions for quality gates and deployment.
- GitHub Pages for serving.
The pipeline
Every pull request runs four gates in parallel. A page that fails any gate does not publish.
Gate 1: structure (markdownlint)
markdownlint-cli2 checks heading hierarchy, list formatting, and code fence hygiene. Five rules are relaxed in .markdownlint-cli2.jsonc, each with a comment explaining why: for example, first-line-heading is off because Docusaurus injects the H1 from front matter.
Gate 2: prose (Vale, Google style)
Vale lints every page against the published Google developer documentation style guide package. Two rules are switched off in .vale.ini, documented inline: the first-person and second-person voice rules, because a portfolio is legitimately written in first person. Turning a rule off with a stated reason is a style decision. Ignoring a linter is not. Error-level alerts block the merge; warning-level advisories stay visible in the logs, where I triage them deliberately rather than silencing the rule.
A small project vocabulary teaches Vale the proper nouns of this site (Qdrant, Docusaurus, GxP terms) so real spelling errors stay loud.
Gate 3: external links (Lychee)
Lychee requests every external URL. The lychee.toml config accepts bot-defense status codes like 403 and 429 as alive, and excludes private addresses because the Qdrant quickstart points at localhost on purpose.
Gate 4: the build itself
docusaurus build runs with broken internal links promoted to errors (onBrokenLinks: 'throw'). Cross-references between pages are the load-bearing walls of a documentation set; this gate means a renamed page cannot silently strand its inbound links.
Deployment
Merges to main trigger a separate workflow that builds once and deploys to GitHub Pages through the official Pages actions. No manual publish step exists, which means the live site cannot drift from the repository.
Why bother, for a portfolio
Because the pipeline is the point. Any writing sample shows what I produce; this setup shows how I work: changes reviewed, style enforced by machine so review attention goes to meaning, and nothing published that fails its checks. I spent eight years inside a heavyweight version of this discipline. The essay Change control was docs-as-code before Git is the full argument.