Local release operations
Consumer access is managed separately from source hosting.
Keep enforcement local
Section titled “Keep enforcement local”Projects that do not use hosted CI can turn off managed workflow generation while retaining local hooks, WU gates and lifecycle receipts:
When omitted, ci.enabled preserves existing CI generation. Setting it to false removes only
the LumenFlow-owned workflow block and regenerates the integrity manifest for local hooks.
Content you wrote around the block survives. Repeated init, enable and upgrade operations
respect the setting. Other project-owned workflows remain under your control.
Run verification where you release
Section titled “Run verification where you release”Use the repository’s pinned Node and pnpm versions. Complete each work unit through wu:prep
and its printed wu:done command. The scoped tests and other required gates still apply.
Certify after landing, then release
Section titled “Certify after landing, then release”The release publishes an already-certified tree. Every wu:done starts the post-land sweep,
which runs the release source-check plan once at each landed commit, in a detached checkout
pinned at that commit, and records a certification: the commit, its status, a digest of the
check plan, and each check’s result and log digest. A red check turns the sweep red and names
the check. The plan includes strict progress, the documentation and packaging checks, the
real-process harnesses, the conformance suites and the full release gate plan, run without
replaying any cached lint or typecheck result. Run it by hand with
pnpm main:sweep --post-land on the main checkout, or standalone in any checkout with
pnpm pre-release:check.
Run the sweep on another machine (offload executor)
Section titled “Run the sweep on another machine (offload executor)”By default the sweep runs on the machine that landed. You can configure an executor that runs the sweep’s offloadable test files on another machine. Tests that need the local machine, such as confinement, loopback servers and real-process suites, stay local.
Set LUMENFLOW_MAIN_SWEEP_OFFLOAD_EXECUTOR to the executor’s absolute path. The path must be an
executable you own that nobody else can write. Otherwise the sweep refuses to run and names the rule.
Nothing falls back to a local run.
The executor receives the job name, the commit and the command. It runs a checkout of that exact commit, streams the output back, and exits with the command’s status. Verdicts from the two halves merge: either red is red. An executor with no verdict is recorded as inconclusive, never green, and the next run for that commit retries.
pnpm lumenflow:release and its --dry-run verify that certification instead of re-running
the plan. They accept the release commit’s own green certification, or one at an earlier
commit when only lifecycle records and documentation changed since. Otherwise they refuse with
a typed message that names the remedy:
| Refusal | Meaning |
|---|---|
uncertified | No certification yet; let the post-land sweep finish, then release |
red | The certification (or the post-land sweep) is red; land the fix first |
inconclusive | A check never got a gates or lifecycle admission slot; no test ran. Run pnpm main:sweep --post-land once the host lock frees |
stale-digest | The certification was made under another check plan; re-certify |
drift | Source changed since the last certification; wait for the sweep to certify it |
integrity | A record or log no longer matches its digest; re-certify |
Cut from the newest certified commit
Section titled “Cut from the newest certified commit”Landings that arrive after certification cannot starve a cut. By default pnpm lumenflow:release
builds from the newest certified commit on the first-parent history of origin/main (the tip
itself when only lifecycle records and docs follow it), or from --at <sha>. When that commit is
not the tip, the version bump commit is pushed to release/v<version> instead of main, the tag
points at it, and the bump is re-applied to main as an ordinary commit. The re-apply is written
structurally on main’s current files, not replayed as a patch: every publishable package main
holds is set to the version (including a package added after the certified commit), and the
version-policy and changelog entries are written on main’s own copies, so a previous release’s
bump or a new package landed since certification does not block the cut. If a manifest on main
cannot be read, the release refuses before release/v<version> is pushed and names the files. If
the re-apply itself fails, the release branch this run created is removed (or the exact
git push origin --delete release/v<version> is printed). A rerun after a partial cut adopts the
release branch and converges.
A cut from a certified ancestor never leaves a landing out silently. Before it starts, the release
prints which landed WUs (and how many commits) it will NOT carry, and the tip that would carry them
once the post-land sweep certifies it. It also names each newer certified commit it passed over and
the rule that rejected it. A post-land sweep that re-reports a failure an ancestor already had does
not reject a commit whose wu:prep evidence is green; a failure the landing itself introduced does.
The certificate is checked against the check plan at that certified commit, not the plan of newer
tooling, so a later change to the release tooling does not block the cut. A certificate that does
not match the plan at its own commit still refuses as stale-digest.
Before each push that establishes the release source, the cut verifies the exact version-bump commit again. If origin moved and the retry rebased the bump onto uncertified source, it refuses before pushing the bump. The refusal names the uncertified source SHA, its landings and changed paths: wait for that SHA’s post-land sweep or the next certified landing, then retry. Lifecycle and documentation advances remain allowed; any other advance still needs valid certification, including an earlier version-bump commit. The separate structural re-apply to main for a cut from a certified ancestor is not the release source and keeps its existing behavior.
Release notes come from changesets
Section titled “Release notes come from changesets”Each work unit that changes released behaviour adds a .changeset/*.md entry. The version bump
commit consumes every pending entry: it writes a ## [<version>] - <date> section in the root
CHANGELOG.md (entries that start with “Behaviour change” or “Breaking” are listed first, under
their own heading, then the rest in file order, each naming its packages), moves the old
## [Unreleased] body under that version, and deletes the consumed files in the same commit. The
PUBLISHED signal links the notes. A pending entry that cannot be parsed (bad frontmatter, an unknown
bump type, an empty summary) refuses the release with that file named, before any version commit.
pnpm lumenflow:release --dry-run prints the notes it would write and changes nothing. Every
package moves to one version on a cut, so the per-package bump types are listed, not applied.
Fast patch releases
Section titled “Fast patch releases”The release-time packed-consumer smoke runs the tools of the commit being released, so newer test
legs never judge older artifacts. Archives upload concurrently (default 4 at a time; set
LUMENFLOW_RELEASE_UPLOAD_CONCURRENCY, at most 8), each package keeps its receipt, and a failed
upload stops further uploads. wu:done certifies a landing by its prep evidence whenever the landed
tree is the tree prep gated and no gate was skipped; it logs the outcome either way. When wu:done
re-runs the gates itself (after an in-run rebase onto a sibling landing, or because the lane changed
since prep), it records a fresh gate checkpoint for the tree it gated, so the landing is certified
against that re-gated tree and not the older prep commit.
A landing that rebased over other certified landings is also certified when its own prep-gated
diff touches nothing that changed since its prep base and no uncertified landing sits in between;
the certificate records the certified parent and the composition. Otherwise wu:done logs why and
the post-land sweep certifies it.
Release incidents and minor/major releases
Section titled “Release incidents and minor/major releases”If a post-land sweep goes red at a commit that a published release tag contains, one urgent
release-incident signal names the version, the failing checks, the sweep run and the hotfix route
(once per version and run). A minor or major release refuses a certificate backed only by wu:prep
evidence (sweep-required) and waits for the sweep; patches and hotfixes are not slowed.
Release-now (patch and hotfix)
Section titled “Release-now (patch and hotfix)”pnpm lumenflow:release --release-now --owner-decision "<the reason, in your words>" cuts a patch or
hotfix immediately from the latest certified commit: no sweep runs, and the consumer smoke test
is the only test step. The decision is recorded verbatim in the certification reuse ledger. The
throughput comparison is printed and recorded as advisory for every patch or hotfix, never a
refusal: the pre-check line reads WARN with the advisory reason, and FAIL is printed only for an
outcome that refuses. Minor and major releases keep it as a refusal and refuse --release-now. A change to
the throughput baseline file never makes certification refuse.
A landing whose tree is exactly the tree wu:prep gated is certified by its own prep evidence when
wu:done lands it, so a release from it waits for no sweep. A landing that merged with other source
changes gets no such certificate and is certified by the post-land sweep instead. The cut itself runs
no sweep: the packed-consumer smoke is its only test step, and a genuine red sweep record at the
target commit still refuses it.
A verified green certification supersedes a red sweep record at a strict first-parent ancestor of its certified commit, however many commits behind it; the release report names the superseded marker. If newer source is uncertified, the refusal names that source and its landing; the old red marker does not replace the real cause. An applicable red marker is named alongside any source or certificate failure. A red record at the certified commit itself, or at any other commit, still refuses. An unverified or tampered green record cannot supersede a marker.
A full cut can outlast a foreground tool timeout, so run it detached and read its log. Rerunning the same command resumes from the retained pin and artifacts.
Right after verifying the certification, and before any version commit, the release runs the
throughput regression check, so a refused attempt costs seconds and pushes nothing. It then runs
only the work that depends on the version, the build or the registry: version and channel checks, the version bump, the minified build, self-consistency,
the exact-archive and pack-root guards, the packed-consumer smoke, pack-registry parity, upload
and read-back, and the tag. Review pnpm release --help and rehearse with
--dry-run; a tag or --skip-publish result alone does not prove that packages are available
to consumers. Configure and verify the intended delivery service before publishing a package.
The release log names every check it ran. Each check prints one line,
[pre-release-checks] PASS <name> (<seconds>s) or FAIL, and the certification line names
the certified commit and the run it reused, so a green release is proof of what ran and how
long it took. The packed-consumer smoke is timed as one lane.
Keep release credentials and consumer license configuration outside the source checkout.