feat: release promotion model with channels and designation-commit promotion - #143
Draft
levifig wants to merge 1 commit into
Draft
feat: release promotion model with channels and designation-commit promotion#143levifig wants to merge 1 commit into
levifig wants to merge 1 commit into
Conversation
levifig
added a commit
that referenced
this pull request
Jul 30, 2026
…bility (#144) Receipt validity now binds to a masked root-tree content digest instead of commit reachability: same HEAD, same verdict, on any clone, under squash, rebase, or merge commits. - Scope digest: SHA-256 over git ls-tree entries minus a declared exclusion set (receipts, report boards, release-metadata allowlist), byte-sorted, mode included, domain-separated; per-top-level-directory sections name drift machine-independently. - Schema v2 receipts: scope digest and sections, exclusions verbatim, digest spec, toolchain, and worktree_clean execution integrity; verified_commit demoted to provenance; cwd dropped; criteria digest covers criterion text. - Freshness is a pure typed predicate; every state is a reasoned block with folder, cause, and remedy. The commit walk and the "cannot inspect receipt" crash are gone. - Verify hardening: refuses dirty tracked worktrees with receipt/report masks exempt so cohort re-verify sweeps compose; voids receipts when criteria mutate the tree or HEAD moves mid-run; config-independent submodule policy; NUL porcelain parsing; bash -c instead of bash -lc. - commandOutput surfaces stderr in returned errors repo-wide. - Fixtures prove the council's defect reproductions: post-squash protocol clone stays verified, N>=2 cohort receipts coexist, byte-identical restore un-stales by design. - ADR-024 pins the serialization and evidence boundary; ADR-023 annotated as superseded where contradicted; the exported boundary is ready for the promotion model's designation check (PR #143). - Five review rounds (internal and external) recorded as boards in the change's reports directory.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Change
docs/changes/20260728-release-promotion-model/ —
target_release: 2.0.0What & Why
Shapes the release promotion model: channels alpha→beta→rc→stable-as-promoted-rc, with stable as a designation event. The CLI surface is
--bumpiterates in place,--promotemoves forward (bare = next rung;releaseexplicit and rc-only),--channelasserts the outcome; the cohort gate moves to rc cut (alpha/beta stay the valve); promotion is one designation commit restricted to release metadata, with the stable changelog re-derived as a rollup that collapses the cycle's rung-labeled sections. Release notes go changeset-pattern: each change authorsrelease-notes.mdin its own folder, CHANGELOG.md becomes a cut-time projection, and the[Unreleased]buffer retires. Distribution routes by channel (loafformula stable-only,loaf-devtracks prereleases). Today the codebase has a single prerelease predicate — no label transitions, no cycle entry, a gate that fires only at stable, channel-blind CI that would hand brew users an alpha after 2.0.0, and a release skill predating the gate entirely.Review focus
Decision 1 (designation commit over tag-only/artifact promotion), Decision 3 (per-channel changelog policy + the exact no-impact token), Decision 11 (CI-green-at-HEAD before tagging), the collapse-set definition (rung-labeled sections of the candidate core; legacy
dev.*/pre.*history survives), and the importedreleaseMetadataAllowlistboundary shared with the receipt-tree-binding predecessor.Verification
loaf change check docs/changes/20260728-release-promotion-model: zero violations, derives executable. Four shaping review rounds are boarded underreports/(R1–R4; R4 attested convergence: 0 blockers, 0 major, 1 minor fixed in-round). V1–V7 declare the executable criteria implementation must satisfy; open items are the two fog entries in shape.md's Open Questions, each with a named owner.Migration / breaking changes
--bump releaseretires with an error pointing at--promote release; the[Unreleased]buffer is removed from CHANGELOG.md, its scaffolds, and the pre-PR hook (re-pointed to per-change note presence). Both land inside this Change's implementation, gated by its own criteria.Deferred
Receipt content binding — predecessor Change
docs/changes/20260728-receipt-tree-binding/(its own PR); capability-evidence decoupling (Intent); concurrent maintenance branches/multi-cycle (revisit on real need); npm dist-tag routing (no npm distribution today).