# Technical Guidance This is a small Next.js application backed by Markdown, with canonical HTML pages, raw text routes, and an `llms.txt` manifest. Preserve that architecture. ## Editorial review comes first Some changes look technical but are editorial. A new content type, a new frontmatter field, a new index page, a new public route, or a change to what `llms.txt` exposes are all editorial decisions before they are implementation ones. For broad changes to content types, public routes, graph structure, or `llms.txt`, check only the directly relevant guidance document. For small mechanical fixes, do not expand into editorial review. The relevant documents are: - `portfolio-strategy.md` for Work section structure. - `writing-style.md` for Journal structure and voice. - `knowledge-graph-index.md` for the internal editorial model. Implementation that runs ahead of editorial decision tends to lock in shape that later has to be unwound. ## Content model Use simple Markdown with clear frontmatter for public content. Expected fields for articles: - `title` - `date` - Optional `status` (`published` or `draft`; omission means published) - A non-empty `standfirst` - `tags` - Optional `location` - Optional image fields only when the image matters. Expected fields for notes: - `title` - `date` - Optional `status` (`published` or `draft`; omission means published) - `tags` - Optional `location` - Do not add `standfirst`; standfirsts are for articles only. Article standfirsts are not currently rendered on canonical article pages or journal indexes. They supply page metadata, RSS descriptions, and the article descriptions in `llms.txt`. Draft entries may live in their normal content directories while they are in progress. They should use `status: "draft"` and remain hidden from canonical pages, raw routes, feeds, `llms.txt`, and the sitemap until changed to `status: "published"` or the field is removed. Status is strict: any value other than `draft`, `published`, or omission is a content error rather than an implicit publication. Expected fields for quotes: - `title` - `date` - Optional `status` - `quote` - `author` - Optional `source` and `sourceUrl`. Expected fields for clippings: - `title` - `date` - Optional `status` - `source` and `sourceUrl` before publication - `tags` - Optional `heroImage` and `heroImageAlt` when the clipping has a ported image. Use `npm run clipping:new -- "Title" "https://source.example/path"` to create a clipping skeleton. Add `--tags`, `--image`, `--concept`, `--entity`, and `--related` when that metadata is already known. Use `npm run clipping:import-images` after dropping old clipping images into `content/clippings/clipping_images`. The importer creates Markdown stubs for unreferenced images and can be rerun safely. New stubs are drafts because an image filename cannot supply trustworthy source provenance or alt text. Missing image references are reported and left untouched; the importer never deletes an existing clipping. Clipping concept and entity connections live in `content/graph/clippings.json`, not in frontmatter. The sidecar should reference concept and entity ids rather than restating their definitions. This keeps public tags sparse while allowing raw routes to carry richer graph context. Journal graph connections live in `content/graph/journal.json` and are exposed through raw journal routes. Keep them out of note and article frontmatter so publishing a piece does not require graph metadata. The sidecar is curated and intentionally partial: an omitted piece has no graph context, while every path that is present must resolve to a live public entry. Keep slugs stable and human-readable. Follow the existing filename patterns in `content/articles`, `content/notes`, `content/quotes`, and `content/clippings`. `content/log` is unpublished draft or legacy material. Do not route it, list it in indexes, or include it in `llms.txt` unless a piece is deliberately migrated into `content/articles`, `content/notes`, `content/quotes`, or `content/clippings`. ## Local development Install dependencies: ```bash npm install ``` Start the development server: ```bash npm run dev ``` Build for production: ```bash npm run build ``` Run TypeScript checks: ```bash npm run typecheck ``` ## Route principles - Canonical routes are for people. - Raw routes are for agents, archiving, quoting, and simple reading. - Articles and notes share `/raw/journal/[slug]`; do not create a second raw article route. - `llms.txt` points to the most useful raw routes and the interpretation rules a visiting model acts on, not to editorial standards. - Public standards in `docs/` are written for people. Surface them through a human path such as the colophon, not through `llms.txt`. A writing or design standard is an instrument for producing the site, not something a visiting model needs to consume it. - Do not let generated indexes drift from content metadata. ## Implementation principles - Markup carries meaning. Reach for a `
` before a `
`, a link before a button. Style follows semantics. - Inspect existing patterns before editing; do not invent a second content pipeline. - Reuse existing components, CSS selectors, content loaders, and metadata helpers. - Keep CSS close to existing global tokens and selectors. - Avoid unnecessary dependencies or one-off rendering paths. - Preserve accessible names, alt text, headings, nav labels, and current-page semantics. - Preserve dark mode as a first-class reading mode. ## Privacy controls Anything in public content directories is considered public. Agents that read the site can crawl raw routes systematically, which means there is no soft boundary that a human reader might naturally observe. If something should not be public to an agent, it should not be in a public content directory at all. - Do not wire private notes or source files directly into the site. - Public content lives in explicit public content directories, not in root private notes by accident. - If generating from private context, create a new public-safe Markdown entry rather than exposing the source file. - Strip confidential company details, financial figures, family specifics, and performance review text unless explicitly approved. - Treat `llms.txt` as part of the public surface. Anything pointed to from it is public to every system that reads it. - Content assets may expose only supported image files inside the established `*_images` directories. Markdown, graph JSON, and `content/log` must never be addressable through the asset route. ## Verification - `npm run build` after route, content-pipeline, metadata, or component changes when practical. - Browser check for layout, navigation, raw routes, and dark mode after significant frontend changes. - Mobile wrapping check for nav, footer, headings, metadata rows, and entry lists. - Validate that `llms.txt` and raw indexes still point to existing routes. ## Technical taste The implementation should mirror the site's editorial taste: small, legible, durable, and easy to reason about. The architecture should survive neglect. It should be runnable a year from now without intervention, readable by a contributor who has never seen the codebase, and useful to systems — search engines, archives, agents — that did not exist when it was built. These are not separate concerns; they are the same concern at different scales. The system should remain understandable without needing hidden operational knowledge. Prefer architectures that reveal their structure plainly through routes, files, naming, and content flow.