When you publish on a platform, you are borrowing an address. Your writing lives under someone else’s name on someone else’s domain, and it stays there only as long as that company allows. You can share the link, but you do not control it because the ground your words stand on is not yours.
Toiling on someone else's domain
Publishing on someone else’s domain is like working on someone else’s plantation. You may do the labour and produce the value, and you may be visible while you are useful. Someone else owns the ground beneath your work and decides what stays or goes, along with what it allows to exist.
Owning a domain changes that relationship in practice. It gives you your own name on the internet and a place where your writing is not conditional on a platform’s rules. Hosting providers and publishing tools can change, but the address that holds your work remains under your control.
That matters because URLs are promises about where something can be found. When you publish a page, you are telling the world that something lives at a particular location. If that location belongs to someone else, the promise belongs to them. If you own the domain, the promise is yours to keep.
That is why self-publishing on your own domain is about freedom as much as technology. A site on an address you control cannot be quietly erased or buried, and another party cannot reshape it. It becomes a place where your writing can exist on its own terms and persist for as long as you decide it should. I want you to own the address before you build the house.
In the early 1990s when Tim Berners-Lee and his colleagues were shaping the World Wide Web, the core idea was simple: this network is for everyone. The web was meant to be a place where anyone could publish and share with links they control. Before social media and platform lock-in, that idea felt direct and practical.
This is for everyone — London 2012 Olympics.
The web’s original promise rested on open protocols and a light technical burden. HTTP and HTML were open enough for anyone to implement, and small enough to understand. If you wanted to publish, you bought a domain and wrote a page then put it online. There was no gatekeeper and no opaque algorithm deciding who saw your work.
Convenience platforms changed the bargain by offering instant audiences and effortless publishing, which made sense for a long time and drew me in. The cost is that your writing lives inside someone else’s system, and your visibility depends on their incentives. The surface looks open, but the platform owns it.
This still matters because a personal site is a form of self-reliance. When you own the domain and the files, you also own the story you are telling. You can publish without asking and keep an archive that outlives a platform, with links that stay stable.
The point here is to keep the original contract intact through open standards and durable URLs, with independent publishing as the practice. This is the ground I want to stand on while I build this site. I insist on open protocols in this system.
I keep returning to the early web’s ideas because they offered a clean technical answer to an ordinary human problem: publishing something and knowing it will still be there tomorrow. You could put a document on a server and give it a URL, and that link would mean something. The page lived on your server, and the link stayed stable because it pointed to a file you controlled.
For a long time, I drifted away from that. Social platforms made publishing effortless by removing hosting work and day-to-day site upkeep, and they bundled identity with distribution and comments while the feed carried the rest. The friction was low and the audience was already there, so the trade felt reasonable even as I gave up control. That convenience has a cost because the platform controls the surface where your work appears and how long it stays visible. Your writing lasts only while it fits inside someone else’s system.
Self-publishing, for me, is a technical choice. Owning a domain and shipping plain HTML means I decide what appears and how long it stays online, with presentation under the same control. A piece of writing stays available while I keep it there, and a page I host will still exist tomorrow if I decide it should.
This way of working also changes how I think about the archive. When everything lives on my own site, I set the rules of what matters and how it surfaces. It is a collection of files and links that I am responsible for. That makes the archive legible and inspectable. It becomes something I can maintain for years without renting it from a platform.
This series is about that choice and treats publishing as infrastructure. I want to write in a space that I control, using tools that do not disappear when a service shuts down. Plain HTML still exists alongside stable URLs and open protocols. I am building with those constraints because they keep the writing mine and keep the system open to anyone who wants to read it or take it elsewhere. This is why I build this system and publish here.
Before the build touches any template, it walks the filesystem and reads frontmatter to construct an index of all available articles. Queries apply to that index to produce explicit, ordered lists of article records. Each query has a name, and that name refers to a specific deterministic result set.
By the time a template enters the pipeline, the interesting work is already complete. It receives the result of a query with a list of article records that already sit in the correct order, whether the list is empty or not.
That is what lets templates stay simple. It keeps the scope small when I need to debug.
A template contains ordinary HTML and one or more <template> tags that act as render slots. Each slot names a query so the build knows what to stamp. At build time, the system takes the results of that query and stamps the corresponding content into the slot. If the query returned nothing, the system uses the fallback HTML inside the <template> tag instead. After stamping, the build removes the <template> tag itself, leaving only normal HTML behind.
Because of this, a template never needs conditionals or loops. It never needs to know how many articles exist or whether a tag is empty, and it does not decide ordering. The build resolves all of that earlier. The template defines where the stamped output should appear and what should show up when there is nothing to stamp.
This turns templating into a mechanical operation. Given the same set of article records and the same queries, the same templates will always produce the same HTML. There is no hidden state and no branching behaviour inside the template files themselves.
It also makes the templates readable in a way that is hard to achieve in more conventional systems. When I open one, I see the page structure as it will exist in the final output. I see the header and navigation, then the main content with its fallback messages for empty sections. There is no embedded logic to mentally execute. The only dynamic pieces are clearly marked as slots.
That is what I mean by calling the system boring. I want the boring sections to stay readable, not clever. The templates stay simple and ignore metadata or sorting rules, while avoiding visibility flags as they provide a fixed shape that content slots into.
Here is a concrete example that matches the home page most readers expect. It is a normal page with a header and navigation plus a list of recent posts. The only special tag is the slot where the build will stamp the query results:
Everything in that file is real HTML. If I open it in a browser, it renders as a page with an empty state because the <template> tag is inert by design. When the build runs, the system replaces that one tag with the output of the latest-posts query. Three returned articles become three summaries in that space, and the build then removes the <template> tag itself. If the query returns nothing, the fallback paragraph remains and the rest of the page stays the same.
That simplicity keeps the system predictable and inspectable, and it stays durable over time. The complexity lives in the build process and the query definitions, where I can validate it and reason about it directly. The templates remain what they look like: static HTML documents with a few clearly defined places where content will appear. If you can read the template, you can understand the page.
If you missed the first piece, start with Why Websites Need Templates. It lays out the baseline that this piece builds on, and it frames why templates exist in the first place.
Once I accept a template as a shared frame for many pages, it becomes tempting to push more work into it. The template already knows about layout, so it starts to feel natural to let it decide which pieces of content appear where. That is how most templating systems evolve, and the shift tends to feel gradual and understated.
At that point the template stops being a simple frame that inserts finished content into a slot. It gets access to a collection of articles and tags plus their metadata. It loops over those items and filters or sorts them, then decides whether certain blocks of HTML should appear. The template now carries structure along with selection and ordering.
At a small scale this feels convenient. If I want a list of recent posts in a sidebar, it seems reasonable to write a loop in the template that iterates over the latest five articles and add a conditional to hide a heading when there are no results. Over time these small decisions accumulate and the behaviour spreads across the layout.
Here is the template logic I am talking about:
{% if featured_posts.length > 0 %}
<h2>Featured</h2>
<ul>
{% for post in featured_posts %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
Short posts I want to surface on the home page.
The result is that the final HTML page is no longer a simple combination of a frame and a piece of content. The output becomes a program embedded inside the template. To understand what the page will look like, I have to consider the template file. I also have to consider the data it receives and the logic that operates on that data. Reading the page becomes dependent on the build.
One consequence is that the template stops being a reliable description of the document. I can open it in an editor and see a mix of HTML and logic, yet I cannot tell which sections will appear in the output for a given build. Another consequence is that it becomes harder to reason about changes, because a small edit in the template or a change in metadata can reshape the output. This is where I start losing trust in the page before I even render it.
Many systems are built this way and people learn to work within those constraints. The template becomes a layer in the site's control plane because it now contains behaviour as well as structure. The file reads like a small program that emits a document.
At that point I find it difficult to talk about a template as a document. The distinction matters if I care about inspecting and understanding the output over time, and about preserving it as a stable artefact.
The next article describes an alternative approach: keeping selection and ordering out of templates entirely, and using them only as fixed stamps that receive already-prepared content. It is the simplest way I have found to keep layout and selection separate. Continue to Templates as Mechanical Stamps.
When I load a web page in a browser, what arrives is a single document. It might be long and include navigation plus footers and sidebars around a main column of text, but to the browser it is just one block of HTML.
When a site grows beyond a handful of pages, I am no longer writing one document but a whole set. Each page carries its own content, yet the structure repeats. The header and navigation stay consistent across the set. The footer and typography stay consistent, as does the layout.
If I were to copy that shared structure into every file, the site would be hard to maintain. A small change to the navigation or layout would require touching every page. Over time those copies drift, and the site becomes inconsistent. This is the practical problem templates exist to solve for me.
A template lets me write the shared structure once and reuse it. I define a common outer document with <html> and <head>, plus a shared header and navigation. The footer sits in the same frame, and I leave one or more places for page-specific content. Each article or page then supplies its own content, and the build places it into those slots.
In its simplest form, templating is just composition. A page is the result of taking some content and placing it inside a larger HTML frame. The content and the frame are separate files, but the output is a single document.
This separation matters because it lets me work on content and structure independently. I can write or revise an article without touching the site chrome. A change to the site chrome does not require me to rewrite the archive. The template system is what connects those two strands.
Once a site grows beyond a few pages, this quickly becomes essential. Without templates, I either duplicate markup everywhere or invent ad-hoc scripts to assemble pages. Templates are the conventional way to express that assembly.
Where templates get more complicated is in how much responsibility I give them. Many systems ask templates to do more than place content into a frame. They ask templates to decide which pieces of content should appear and in what order, sometimes with conditions. That turns the template into a control layer with decisions baked in.
Whether that is a good idea depends on what I want from my publishing system. That is why I want templates to act as mechanical stamps that receive prepared content. I use the next piece to make that trade-off explicit.
In the next article I look at how that additional responsibility changes what templates are, and why it affects the clarity and predictability of the final HTML. If you want to continue, head to When Templates Start Making Decisions.
I write this down early because it is the anchor I will keep returning to and the blog only works if it lets me publish day to day technical work without friction while AI drafts alongside me and I keep control of the final voice. That constraint is the condition that makes the rest of the system worth building.
The centre of it, for me, is the web itself. I keep coming back to classic HTML and the original web idea from Tim Berners-Lee. A document should read cleanly in source and still make sense without scripts, and a link should act as a stable address with no runtime dependency. I want this site to feel like the early web did when it was a network of human readable documents where the page is the page and the URL means what it says.
That stance forces decisions about durability and access. Accessibility and internationalisation are not optional if I want the site to last, so headings and landmarks must make sense to assistive tools and links must remain clear. Text and layout choices cannot collapse when language or fonts change, or when the reader never uses a mouse. Performance and cacheability live in the same layer. Pages need to load fast on slow networks and stay responsive on old devices.
Discoverability sits beside all of that, so clean URLs and meaningful titles should show their intent without JavaScript. Indexable pages should do the same work to show intent. SEO and AI visibility should follow from clear structure and plain metadata, without overlays or tricks. I will use unobtrusive JavaScript where it helps navigation, but I keep the baseline page intact with classic HTML as the foundation.
The tooling has to match that posture, so I favour a minimal toolchain and native JavaScript while keeping the feature scope tight. I will add theming and user settings only when they serve reading.
This spec should grow by addenda so the trail stays visible. I am writing the blog while building the blog, and that loop stays central. A philosophy should show in the site, and the site should reveal any drift. Tags: philosophy, web
I built the repository to be the blog and the build system with the record of how the build changes kept in the same place. That sounds neat as a concept, but it is also a practical choice. If I keep the content in a single place and put the scripts that shape it in the same place, I can read the whole system like a diary where the log of work becomes the work and the writing lives inside the software taking shape.
This idea changes how I think about content. A post is a folder with a Markdown file and nearby assets, plus a small amount of metadata that makes indexing possible. The folder tree is the public rhythm of the blog. Dates become paths and months become folders, so each post sits as a leaf in the tree. I can point at the layout and show how the site thinks.
It also changes the role of automation. I rely on a handful of scripts that are obvious when I read them, because that makes the system legible to me and to the AI that maintains it. The scripts handle repetition, and the repo holds the permanent record. When the AI adds a script, it becomes an event in the diary and the change itself becomes content so the build system learns in public.
The same principle applies to templates, which are plain HTML and only stamp content into a page. Queries decide what exists, and those queries live beside the content they select. That is the heart of this approach. The data and selection stay visible, and the render stays visible too. When I say that the blog is the build system, I mean that the entire path from idea to page is traceable inside one repository. If you want to inspect how the system works, you can read the archive and follow those decisions in plain sight.
I do this because I want to write about building the blog while I build it. The first posts will be about the system that is learning to publish the posts. I am comfortable with that because I treat the system as a living artifact. The repo is the journal, which becomes the site and the build.
I treat indexing as a query problem, not a rendering problem. Every list on the site comes from a named query that selects a set of articles and a sort order. That keeps selection declarative and repeatable, and it keeps logic out of templates.
Queries live in JSON, not inside templates. A template names the query and provides a slot. The build fills that slot with either summaries or full article bodies. The template never decides what exists, and it never learns how selection works.
This separation keeps indexing logic small and inspectable. If a list looks wrong, I can read the query and see exactly why those items appear. The build avoids inference and guesswork, which prevents hidden selection and keeps the lists predictable.
The constraint is intentional because queries are plain objects, not a DSL. They cannot grow into a second programming language. That limit is a feature: it prevents hidden logic and keeps the system declarative, not imperative.
Feeds follow the same rule, and the global feed plus tag or series feeds come from named queries that avoid scraped HTML. That keeps discovery aligned with the rest of the site and makes the outputs small and deterministic.
I can change a template without changing the data, or refine a query without touching markup. Indexes remain mechanical outputs of named inputs. The result is no surprise lists and no invisible filters.
I treat the archive as an ordering problem once articles exist as files with frontmatter. The same set of entries groups in different ways depending on what a reader wants. Two of those groupings matter here: series and tags.
A series describes a narrative and carries the idea that one entry follows another, so reading in order carries meaning. Series pages group all articles with the same series value and sort them by date ascending. The first article sets context and each one extends it, so the list grows forward in time.
Both groupings come from the same frontmatter table. Each article contributes a row with its date plus tags and series. The build applies different sorts to that same data. I need no extra structure in the files themselves. What changes is how I shape the list.
This distinction lets the archive behave in two different ways at once. A series behaves like a log or a chaptered notebook, where order carries weight. A tag behaves like a topical index, where breadth and freshness matter more than sequence. The same article can sit inside both without conflict, because one describes its place in a story and the other describes what it is about.
When you want the story, follow a series; when you want the latest on a topic, follow a tag.
I write the body for readers and use frontmatter so the build can work without reading it. Everything above the YAML divider supports indexing and ordering along with layout. The build reads this small structured block and stops. That boundary keeps the prose for people while the data stays available to the pipeline.
A typical frontmatter block looks like this:
title: "An Article Is a File"
summary: "How each entry in this blog reduces to a single Markdown file. The body stays human, the header stays machine."
series: genesis
tags: [publishing, process, tooling, structure]
status: published
thumbnail: assets/hero.jpg
Those fields form the row for this article in the site's internal table. Titles and summaries let index pages render without scraping prose, and the series value places the article inside a forward-moving narrative. Tags attach the entry to topics, and status controls visibility. The thumbnail gives lists a concrete image.
This separation lets writing and indexing evolve independently. A list title may not match the heading inside the article, and a summary may never appear in the prose. I keep that duplication because it keeps each surface predictable and keeps the body readable even when the index logic changes.
From a tooling perspective this keeps the pipeline simple. Scripts parse YAML and collect rows, then apply filters and sorts without reading the body. That keeps selection mechanical and prevents hidden inference. Everything that participates in queries and lists lives in one place, in a form that stays stable even as the writing changes.
An article rarely stands on text alone. Screenshots and diagrams sit beside photos and small media files in the same unit of work as the writing they support, and I keep them together for that reason. In this system those files live beside the article that references them so each entry stays complete and portable. A typical article folder looks like this:
article.md holds the writing and the assets/ folder holds the attachments. There is no shared media pool and no global upload directory, so each article carries its own supporting files. That choice keeps the archive legible on disk and makes it obvious which files belong to which entry.
The Markdown body names assets by relative path, and the build resolves those paths to absolute URLs anchored to the article permalink. The source stays clean, and the output stays stable. That keeps links predictable when the archive grows. It also keeps review simple because the path stays visible in the prose.
Because the image sits next to the file that references it, the source stays stable when the folder moves or the repository gets cloned. The build converts that source path into a permalink-safe URL so the same image works whether the article appears on its own page or inside an index. That behaviour makes it safe to reorganise the archive without breaking links.
Images serve different roles across the site, and some get promoted into indexes as thumbnails while others appear inline as diagrams or screenshots. That distinction comes from frontmatter and templates, and the Markdown only names the file. The writing stays focused on content while the presentation stays elsewhere. I can change that presentation later without touching the text.
The same approach applies to any other asset, including animated images and small videos as well as data files or reference PDFs. The build copies the assets/ folder into the output tree and preserves the on-disk structure while emitting absolute URLs in rendered HTML. That keeps the output predictable and the source portable.
Nothing in the article body needs to know how the site will present an image because it only names a file. The template decides whether that file becomes responsive or lazy-loaded, and how it gets styled for the page. That keeps the body light while the layout carries the polish.
That boundary keeps the writing stable, so I can edit a paragraph or add a code block without worrying about the rest of the system even when I drop in a diagram. The file remains text with attachments and the build system turns it into a page. The body stays clean because it has to, and it is the place where all of this meets a human reader.
Frontmatter defines an article for the build, but the body carries the meaning for readers. It is the section a reader actually meets, so I treat it as the record that must survive every build. Everything below the YAML block exists to be read, and that focus drives the format and the discipline. The body holds the text and keeps links and code beside the media, so the file stays readable before and after the build touches it.
Markdown keeps the text close to plain language. Paragraphs and headings read the same in a terminal or a diff viewer, so the file stays legible wherever it travels. That consistency lets me review drafts without leaving the file. That stability is why I keep the body in Markdown even as the rest of the system shifts. I begin the body with the title and date line so the file stands on its own and the reader can orient without metadata. Sections use normal Markdown headings, which keeps the body free of page and layout syntax.
Layout lives in templates and the body stays focused on narrative structure. I add section breaks to serve the argument, and the template controls how headings appear on screen. Links point to published URLs and stay explicit in the prose, which keeps filesystem paths out of the body. Code blocks use fenced Markdown and avoid inline tooling because the code exists to be read. Syntax highlighting can happen in the browser when it helps.
Images and other assets sit in the same folder as the article, and the Markdown references them by relative path so the entry stays self-contained when the folder moves. The build copies that folder into the public tree and keeps the same structure in place, which keeps images working in indexes and on their own page. The body avoids embedding logic and keeps lazy loading in templates, while the Markdown stays presentation-agnostic and media framing stays in the layout layer. That boundary keeps the writing stable, so I can edit a paragraph or add a code block without worrying about the rest of the system. The file remains text with attachments, and the build system turns it into a page.
These posts describe the system that publishes them, and they do so in the same format as every other article. That keeps the documentation inside the pipeline, and the body serves as evidence of the approach. When the build changes, the archive stays reliable. If an idea cannot live inside Markdown with links and headings, I treat that as a design problem and fix the system until it can. The article body stays simple because it is the only place a human meets the work, so everything else can remain mechanical.
I treat each article as a single Markdown file inside its own folder because I want the archive to stay inspectable and durable. A reader can open the file and see the full text in a stable shape, which keeps the record legible years later. You can also clone the archive and read it in plain text when the build changes.
Each entry lives in its own folder. The folder path carries the date and slug. The file carries the writing, so URLs stay aligned with edits.
Open article.md in any entry and you always see the same two-section structure. A YAML block sits at the top and the Markdown body follows, which keeps the writing distinct from the data surface.
---
title: "The Shape of the Archive"
summary: "How this blog organises itself on disk instead of inside a database. The path does the work."
series: genesis
tags: [tooling, publishing]
status: published
thumbnail: hero.jpg
---
Here is where the writing begins…
Everything above the divider is frontmatter for indexing, and everything below it carries the published text. The build reads the YAML block to assemble lists for series and tags, then renders the body as the article page. That keeps selection mechanical and keeps templates focused on structure.
Some values appear in both places because each surface has a job. Titles and summaries belong in lists, while the article uses its own headline. A summary can stay out of the body so indexes stay concise. That keeps index pages tight while the article stays expansive. It also keeps readers from re-reading the same text in two places.
From a tooling point of view this keeps articles easy to work with. The file reads cleanly in a text editor. The metadata parses cleanly in small scripts. Git diffs stay tight enough to scan in seconds.
For readers this means the permalink remains stable and the record stays open to inspection. For me it means a predictable build and a file I can review years later. That durability is the payoff of treating the file system as the source.
Writing quickly matters to this project because without it I'd slow down and publish less. The pace drives the experiment because ideas form in real time and I make decisions under pressure, so the value is in capturing them while they're still alive. That creates tension: speed pulls me toward shortcuts and familiar phrasing that drain the work of voice.
It's easy to slide into that as certain phrases arrive fully formed and sentences drift into explanation while leaving description behind. Paragraphs climb into commentary about the writing. Language has grooves, so when I'm moving fast I let the wheels fall into them.
Automation helps here, even though it's awkward. I don't believe there's a reliable way to algorithmically judge good writing, and I'm not trying to invent one. What I do think is possible is to detect laziness. I watch for repetition and familiar scaffolding, then for verbal tics that appear when attention drops or when a phrase announces an idea before it arrives because those patterns show up quickly.
The prose-lint script most often catches short scene‑setting lines that do no work. It also flags contrast framing that drifts into meta narration. It flags tidy lists of three that flatten nuance. Those are the signals that my attention slipped and the prose started to coast.
This project will involve writing local scripts that scan prose and score it for those habits. The scripts are friction: no rewrites, no house style, just a mirror. If a draft trips too many signals, that's my cue to slow down and look again because the tooling doesn't decide what's good.
There's something slightly perverse about using code to guard against formulaic writing, but it fits the larger theme here. Staying awake is the point, so fast writing only helps when it still sounds like someone thinking without the shape-filling feel of a system. A bit of automation that keeps me alert while I move quickly feels like a fair trade.
In case it wasn't obvious, yes of course I will be employing AI to help me write and help me review my text content. Learning how to do this in a timely manner without producing soulless slop is one of the big challenges of this project and one of the design goals is to help me as the writer use the assistance of AI without ever putting it in the driver's seat.
Steve Jobs once said "the computer is like a bicycle for the mind". The way I've been thinking about it lately, AI is like an e-bike for mine. Let's hope it doesn't drive me into a ditch!
I'm building this in public because writing details down changes how I think. When ideas stay private they remain vague and provisional. When I write for others, even an imagined reader, the ideas sharpen. Assumptions surface and decisions harden, which is where the gaps show.
This repository is where I'm working decisions out and where those workings live. The notes and specs sit beside the code they shape, with half-decisions and revisions kept close by. They stay inside the process, present while I shape the code.
The writing is one of the tools I'm using to build the system. It affects the choices I make and keeps the work accountable because it has to be readable to someone besides me.
One concrete example: when I wrote down the rule that templates should remain pure HTML, it stopped me from adding conditional logic in a rush. That single paragraph forced me to move selection into named queries and keep the rendering mechanical, which is now a fixed constraint in the build.
A central concern in the experiment is how AI fits into this. I want AI as a constrained collaborator with clear boundaries about authority and intent, along with what I allow to change. Those constraints preserve the shape of the work while still letting me use speed and advantage when they help.
The blog that will appear here comes from the project and follows the same rules. As the repository grows, the system that publishes it will grow alongside it. Templates and queries will show up alongside build scripts and deployment, because the writing needs them.
I still work out my position, and I take my time with it. This is an attempt to think carefully and design slowly while leaving a readable trail behind. The trail should stand on its own, even if I am the only person who ever reads it end to end.
This project exists to test a new model of software development and content production in public. The repository is both the lab and the record, and the system I am building will publish the discoveries that come out of its own construction. If you want the map of how the system thinks, treat this series as a lab notebook with working notes and decisions in view. I want readers to see the system forming alongside the result.
The first content is the documentation process itself, so I write while I build and treat the conversation and decisions as raw material with constraints and contradictions kept visible. The Q/A process I am working out here is the real work, and it becomes the content. Each entry shows a decision while it is still forming, before it hardens into tooling.
Over time, this back-and-forth will harden into scripts as the workflow stabilises and the content aligns with the system it describes. The point of doing it in the open is that the system proves itself by publishing its own formation. The diary becomes the tool because each change leaves a record I can test and reuse.
I minimise imports and treat third-party tools as last resorts. If I can solve a problem cleanly in a small amount of code, I do it myself and I understand it. If that stops being true, I bring in a dependency with intention and say why.
On the publishing side, I am aiming for the most boring convention that still works: a home page index with the newest post at the top. Each post also gets a dedicated article page with a stable permalink. That is the shape of the site I want to live inside. It lets me read the archive as a plain list without extra machinery. It also keeps the build simple enough to inspect.
This is the beginning of the genesis series. Read the posts in order if you want the narrative and the mechanics together. The sequence is the intended path through the decisions that shaped the build.