Changelog

It's not done until it ships.

Fixed

Articles pointed answer engines at one shared image

A shared article showed the same site-wide card as every other page, and the BlogPosting image pointed there too. Each article had its own opengraph-image card, in an emerald palette the design system had retired. The image now points at that card, redrawn like the article masthead in Brand kit paper, grid, and ink.

5 of 5 published articles moved to their own image
Added

Article bylines credited me in plain text

Each article byline was a plain-text name. Answer engines read the visible HTML rather than the JSON-LD, so the credit has to be on the page. The name now links to the About page with rel="author", and an author card adds my role and bio from the brand.ts file, plus a LinkedIn link.

Added

A style gate catches what the slop gate cannot read

This page shipped three British spellings, a missing serial comma, and a gerund. The slop gate passed all of them, because it reads AI tells and ignores style. A new check in verify now fails on spelling and on a missing metric, and warns on serial commas and blurb length.

11 failures on the unfixed file, 0 after
Added

Writing rules arrive with the prompt that asks for copy

A writing rule in CLAUDE.md did not hold across one long session, and public copy shipped in a guessed voice. A UserPromptSubmit hook now reads each prompt for a copy signal and injects the writing process as context. It never blocks a prompt, and it stays silent on a coding prompt.

Fixed

Identity copy passes the slop gate before it ships

The brand.ts file holds the copy that every page and profile reads, and it shipped AI slop with no gate over it. The pre-commit slop check covers it now. Its first run flagged Core Web Vitals as the filler word vital, so I fixed the checker, and real filler still trips it.

3 false positives cleared
Fixed

Secrets masked before tool output leaves the machine

Command output passes through a redaction gate on its way to the transcript and the trace store. Tests for the key formats this stack uses took it from two of seven shapes caught to all seven. A review then found six more leaks, and I fixed each one with a failing test first.

7 of 7 key formats masked
Added

One command runs every check the pipeline runs

Lint, formatting, types, tests, and five project guards run in one command before a push. CI calls that same script, so the machine the code is written on cannot drift from the one that gates it.

9 checks in 9 seconds
Fixed

Deploy guards were canceling each other

Four checks shared one concurrency group, so a release canceled its own gates, skipped the deploy, and left production a commit behind. The merge looked clean, so only the deploy result showed the failure. Each guard has its own group now.

Improved

CI spend scoped to what the change touches

Superseded runs cancel, drafts run nothing, and each guard runs only on the paths that can affect it. A spend report prints minutes per workflow and flags a truncated window.

271 minutes measured across 30 days
Added

Copy quality gated before the commit

A pre-commit hook reads the staged copy, frontmatter prose included, and blocks anything that adds an AI tell. It runs locally, so careless copy costs no CI minutes.

Improved

The design system is enforced by the linter

The theme reads the site tokens directly, and lint fails on raw color values and on classes Tailwind cannot generate. The error names the token to use.

Shipped

A red check blocks the release

Vercel publishes a build on every push by default. This repo turns that off. The deploy job lists all four guards as prerequisites, so a red check stops the release before it starts. A planted second lockfile proved it.

4 guards, proven with a planted lockfile
Added

git-cliff regenerates the developer changelog after every deploy

Inside the deploy job, git-cliff reads the commit history and regenerates the CHANGELOG.md file, then commits the result. This page is a separate log that I write by hand and review before it ships.

483 entries, none written by handView the dev changelog →
Fixed

Draft pull requests skipped every check

The pull_request trigger did not list the ready_for_review event, so when a draft became ready, no guard ran and the pull request showed an empty check list. All four guards list the event now.

Get in touch

Working end to end across design, creative, and engineering, where creativity, collaboration, and ownership build toward the company's goals.

jeffkliu@gmail.com