Skip to content

Changelog

Substrat ships continuously. Every Monday this page gains an entry for the week just ended: the handful of changes that alter how you build on the platform, written out in full, and a complete accounting of everything else that landed.

Weeks are listed in the sidebar, newest first.

Get it by email

The same entry, by email, the morning it is written — no separate edition and no marketing wrapped around it. One confirmation email first; nothing else until you click it.

The first issue has not gone out yet. Confirm your address and you will be on the list when it does.

What this is not

It is not the package changelogs. Every published package carries its own CHANGELOG.md, generated by changesets from the changeset each PR declares. Those answer a precise, narrow question — what changed in @substrat-run/kernel between 0.86.0 and 0.87.0 — and they answer it per package, in isolation, which is exactly what you want when a version bump breaks your build.

This answers a different one: what happened, and does it change how I write a vertical? A single week's work usually crosses the kernel, the contracts, two engines, the host and the scaffold at once, and no per-package changelog can show you that shape. Each entry closes with the version spans the week produced, so the two views meet.

It is not release notes. Substrat is pre-1.0. Interfaces move without a deprecation window, and an entry will say so plainly when they do rather than phrase a break as a feature.

How an entry is put together

Highlights are written, not generated. A digest is an editorial act, and the repo's rule for generated files — a .generated suffix, a header naming the producer, and a --check re-emit in CI — is deliberately not claimed for prose that no producer could re-emit. A file that says it is generated while nothing regenerates it is worse than one that admits an author.

What is mechanical is completeness. pnpm lint:changelog --check reads each entry's declared range, walks git log for the merges inside it, and fails if any merged pull request is not named in the entry (a commit pushed without a PR has no number to name, so it is reported for the author to cover, not failed on). The prose names no pull requests — it is written for someone building on the platform, who has no reason to open the repo — so each entry ends with a ledger of the merges it covers, in a comment that does not render. An author who drops thirty PRs out of ninety produces a page that reads as finished and is not, and the only way to catch that by hand is to redo the work.

The hard parts, hosted.