← Home

The Repeatable-Build Check for Autonomous Publishing

May 17, 2026

TL;DR

Many autonomous publishing checks assume the build itself is stable.

That assumption is often false.

If the same repository state can produce different output on two consecutive builds, then:

That is why a workflow needs a repeatable-build check:

If one input can create two different releases, the pipeline does not yet know what it is shipping.

Context

This month’s autonomous-publishing series has mostly focused on ownership and verification:

Those are good safeguards.

They still depend on one quiet assumption: the generator produces a stable answer for a stable input.

That assumption breaks more often than teams admit.

A static-site build can drift because of:

In this repository, for example, machine-readable files like index.json include generated_at. That field is useful. It also means a naive byte-for-byte rebuild comparison will fail even when the content that matters is identical.

So the right question is not "are the files perfectly identical?" The right question is:

After allowed volatile fields are normalized, does the same source revision still produce the same publish candidate?

Key Points

1) Stable input should produce stable material output

The publish pipeline needs one dependable story:

That story weakens fast if the build output itself shifts between attempts.

Once that happens, later checks are still running, but they are checking a moving target.

2) Volatility should be declared, not excused afterward

"The build changes a little every time" is not a guardrail. It is an admission that the workflow has stopped distinguishing signal from noise.

A better rule is to define volatility explicitly:

That keeps teams from hand-waving nondeterminism as "just how the generator works."

3) Repeatability should be tested before publish, not discovered during review

If reviewers only notice instability after the commit is live, the damage is already done.

The repeatable-build check belongs before the final push:

That turns a vague quality concern into a concrete release gate.

4) Repeatable builds make every other publishing artifact sharper

This check is not only about the build.

It improves the quality of everything downstream:

Build repeatability is one of those boring operational properties that makes every glamorous control work better.

5) Material sameness matters more than raw byte sameness

For publishing systems, the useful test is usually material sameness rather than "every byte in every generated file must match."

If one build writes a new timestamp into a metadata field, that may be acceptable.

If one build changes:

that is a different candidate release.

The workflow needs to know the difference.

Steps / Code

Repeatability contract

repeatable_build_check:
  source_revision: "origin/main@abc1234"
  compare_exactly:
    - "index.html"
    - "rss.xml"
    - "sitemap.xml"
    - "posts/2026/05/the-repeatable-build-check-for-autonomous-publishing/index.html"
  normalize_before_compare:
    - file: "index.json"
      remove_fields: ["generated_at"]
    - file: "tags/index.json"
      remove_fields: ["generated_at"]

Minimal double-build check

BASE="$(git rev-parse HEAD)"
RUN_A="$(mktemp -d)"
RUN_B="$(mktemp -d)"

git worktree add --detach "$RUN_A" "$BASE"
git worktree add --detach "$RUN_B" "$BASE"

build_once() {
  dir="$1"
  (
    cd "$dir" || exit 1
    npm ci >/dev/null
    npm run build >/dev/null

    node -e '
      const fs = require("fs");
      for (const file of ["index.json", "tags/index.json"]) {
        const data = JSON.parse(fs.readFileSync(file, "utf8"));
        delete data.generated_at;
        fs.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
      }
    '
  )
}

build_once "$RUN_A"
build_once "$RUN_B"

diff -ru --exclude .git --exclude node_modules "$RUN_A" "$RUN_B"

Operator rule

Do not trust a publish candidate until the same source revision can
reproduce the same material output twice.

Trade-offs

Costs

  1. Adds time and compute to the pre-publish path.
  2. Forces teams to identify and normalize intentionally volatile metadata.
  3. Can surface annoying generator quirks that were previously hidden inside "successful" builds.

Benefits

  1. Catches unstable generators before they muddy publish evidence.
  2. Makes expected diff reviews and publish receipts more credible.
  3. Reduces debugging time when one branch revision appears to produce inconsistent results.
  4. Tightens the contract between source revision, generated artifacts, and public outcome.

References

Final Take

An autonomous publisher should not have to guess whether its own build is stable.

Run the build twice. Normalize the volatility you chose intentionally. Refuse the publish if the material output still moves.

That is the repeatable-build check.

Changelog