System, not blog

Four design decisions that make this a system rather than a blog.

Decision 1

Articles as typed records, not CMS entries

Every article on this site is a TypeScript record. Not a database row, not a CMS document, a typed object that the compiler validates. The type system enforces that every article has a title under 72 characters, an excerpt under 180 characters, at least two tags, a feature image with alt text, and a hero section.

This is the "content as code" approach. It means the quality rules are in the type system, not in a style guide that someone has to remember to check. If an article violates a rule, the build fails. It cannot be published. The constraint is structural, not procedural.

Decision 2

Topic cluster architecture enforced at build time

The content is organised into four silos (Automation, Data Visibility, Integrations, From Chaos to System). Each silo has one hub article and multiple cluster articles at different depths: core foundations, applied examples, and adjacent references.

The relationship is enforced by the content model: support articles belong to a silo, the silo has one default hub, and the graph uses explicit cluster depth and graph placement metadata. This prevents the most common content architecture failure: the structure that exists in the content calendar but not in the actual site.

Decision 3

Structured data for every relationship

Every hub article has FAQPage JSON-LD schema with the questions it answers. Every non-hub cluster article can expose an isPartOf relationship to its silo hub when that relationship is visible on the page. Every silo page has CollectionPage schema listing its articles. The site has WebSite schema with a SearchAction.

This is not decoration. FAQPage schema helps machines understand explicit question-answer content. isPartOf makes the hub relationship machine-readable. CollectionPage tells crawlers that these articles are curated together for a reason.

Decision 4

A knowledge graph that shows the structure to humans and machines

The articles page includes a visual knowledge graph (toggle to "Map") that shows hubs, cluster articles, and cross-silo links as an interactive SVG. Hub size scales with cluster article count. Cross-silo links show as dashed connections between clusters. Click a hub to see its cluster in detail.

The graph has a semantic fallback: a hidden nav element with the full structure in crawlable HTML. When AI crawlers index the page, they see explicit topic relationships and cross-article links in structured HTML, not just a list of articles.

The validation system

Quality rules that run at build time so nothing bad ships.

The validation layer is where the content system earns its name. These are not style guidelines: they are enforced constraints that prevent content from publishing if it violates the rules. The build fails, the problem is described, and nothing ships until it is fixed.

What gets enforced

Rules that run before every build

Slug uniqueness and format (lowercase kebab-case, max 72 chars) prevents duplicate URLs and SEO-unfriendly paths.

Title and excerpt length prevents titles that get truncated in search results and excerpts that overflow Open Graph cards.

Hub word count and support article word count enforce the quality floor that makes content worth citing.

Hub FAQ questions (minimum 2) ensure every hub article has structured question-answer pairs for AI citation.

Cluster membership prevents orphaned support articles and broken content hierarchies.

Internal relatedLinks URLs must resolve to real articles, Builds items, service paths, or contact actions.

Duplicate graphOrder per hub and depth prevents two cluster articles from claiming the same map position.

The production judgement

Content as code fits a solo builder. A team adds a CMS on top, but the same rules transfer.

The validation logic, the type definitions, and the schema architecture are all separable from the "articles in TypeScript" implementation. The rules could become CMS publish conditions. The type system could become a CMS content model. The JSON-LD generation could become a CMS plugin.