From d26337aaf3ec00be58b62d146caec82d6f236142 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Thu, 9 Apr 2026 16:27:19 +0100 Subject: [PATCH] Promote v6 to rc.2 stabilization --- VERSION | 2 +- docs/release-control/control_plane.json | 6 +-- .../v6/internal/PRE_RELEASE_CHECKLIST.md | 16 ++++--- ...-publication-judgment-packet-2026-04-09.md | 42 ++++++++++++------- ...-promotion-readiness-blocked-2026-04-04.md | 8 ++-- docs/release-control/v6/internal/status.json | 31 +++++++------- docs/releases/RELEASE_NOTES_v6.md | 4 +- .../release_promotion_policy_test.py | 6 ++- 8 files changed, 61 insertions(+), 54 deletions(-) diff --git a/VERSION b/VERSION index 420dc8d24..0ee28d89d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.0-dev +6.0.0-rc.2 diff --git a/docs/release-control/control_plane.json b/docs/release-control/control_plane.json index af5a4cd92..8bd8c8a84 100644 --- a/docs/release-control/control_plane.json +++ b/docs/release-control/control_plane.json @@ -6,7 +6,7 @@ "control_plane_doc": "docs/release-control/internal/CONTROL_PLANE.md", "control_plane_schema": "docs/release-control/control_plane.schema.json", "active_profile_id": "v6", - "active_target_id": "v6-rc-cut", + "active_target_id": "v6-rc-stabilization", "profiles": [ { "id": "v6", @@ -30,7 +30,7 @@ "id": "v6-rc-cut", "profile_id": "v6", "kind": "release", - "status": "active", + "status": "completed", "summary": "Hold Pulse v6 on the governed prerelease-cut target until RC publication is explicitly judged ready, while continuing to clear prerelease blockers, prove migration safety, and exercise the pre-RC high-risk gates.", "completion_rule": "rc_ready" }, @@ -38,7 +38,7 @@ "id": "v6-rc-stabilization", "profile_id": "v6", "kind": "stabilization", - "status": "planned", + "status": "active", "summary": "Once a real governed RC exists, keep Pulse v6 simple, accurate, and cleanly readable around that proven monitoring-first floor while broader control-plane expansion stays out of the default target until it is proven.", "completion_rule": "manual", "proof_scope": "none" diff --git a/docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md b/docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md index 0228b710d..6a1081093 100644 --- a/docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md +++ b/docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md @@ -13,17 +13,15 @@ Use this as the final gate before cutting a Pulse v6 pre-release. ## Current Status - Automated command-driven checks completed on 2026-03-06 are marked `[x]` below. - `status.json` is no longer overclaiming threshold-unmet gates as passed. -- There are no remaining `rc-ready` high-risk release-gate blockers, but - `rc_ready` is intentionally held false in `status.json` by the open decision - `rc-publication-judgment` until the current candidate is explicitly judged - ready for a real governed RC. +- There are no remaining `rc-ready` high-risk release-gate blockers, and the + explicit `rc-publication-judgment` was approved on 2026-04-09 for the first + governed Pulse v6 RC. - The latest RC publication judgment packet is `docs/release-control/v6/internal/records/rc-publication-judgment-packet-2026-04-09.md`. - The full active-target proof now passes; the remaining blocker is the - explicit owner judgment on whether to publish a real governed RC. -- The active target is back on `v6-rc-cut`, so GA rehearsal remains - intentionally out of scope until a real RC has actually shipped and - promotion is resumed explicitly. + It now records approval, not a proof blocker. +- The active target is now `v6-rc-stabilization`, so the governed RC floor is + complete and GA rehearsal remains intentionally out of scope until a real RC + has actually shipped and promotion is resumed explicitly. - The remaining release-ready blocker is `rc-to-ga-promotion-readiness`, which stays blocked until a later stable `6.0.0` candidate completes a matching `Release Dry Run` rehearsal with the canonical promotion artifact envelope: diff --git a/docs/release-control/v6/internal/records/rc-publication-judgment-packet-2026-04-09.md b/docs/release-control/v6/internal/records/rc-publication-judgment-packet-2026-04-09.md index d22485edc..11e24e1ae 100644 --- a/docs/release-control/v6/internal/records/rc-publication-judgment-packet-2026-04-09.md +++ b/docs/release-control/v6/internal/records/rc-publication-judgment-packet-2026-04-09.md @@ -4,12 +4,12 @@ - Decision: `rc-publication-judgment` - Active target: `v6-rc-cut` - Active branch: `pulse/v6-release` -- Result: `blocked` +- Result: `approved` ## Scope -This packet prepares the explicit owner judgment for publishing a governed Pulse -v6 RC. It does not make the product approval decision. +This packet records the explicit owner judgment for publishing the first +governed Pulse v6 RC from the current `pulse/v6-release` candidate. The current release-control target still uses the `rc_ready` completion rule. GA or stable promotion remains out of scope until a real prerelease has shipped @@ -159,23 +159,33 @@ rc-ready assertion set. 4. All rc-ready release gates passed. 5. `rc-publication-judgment` as the only remaining rc-ready blocker. +## Owner Decision + +On `2026-04-09`, the owner explicitly judged the current `pulse/v6-release` +candidate ready for the first real governed Pulse v6 release candidate. + +This resolves `rc-publication-judgment`. The technical RC floor is already +proved; the remaining work is operational release execution on the governed +branch. With that approval recorded, the control plane should promote from +`v6-rc-cut` to `v6-rc-stabilization`. + ## Judgment Outcome -Do not clear `rc-publication-judgment` from this packet. +Clear `rc-publication-judgment` from this packet. -The release-control proof floor is now satisfied, but prerelease publication is -still an explicit owner product decision rather than an automatic consequence of -passing proof. This packet is now ready for that judgment; it does not make the -judgment itself. +The release-control proof floor is satisfied and the owner has approved the +first governed Pulse v6 RC publication. This packet now serves as the decision +record for that approval; it does not change the later GA/stable policy. -## Required Unblock Steps +## Required Release Actions -1. Review this packet as the explicit RC publication decision input. -2. If the owner judges the current candidate ready for a real governed RC, - resolve `rc-publication-judgment` explicitly instead of treating proof - completion as implicit approval. -3. If the owner does not approve publication yet, keep - `rc-publication-judgment` open and record the reason as a product decision, - not a missing proof. +1. Bump `VERSION` on `pulse/v6-release` to `6.0.0-rc.2` and commit that change. + `v6.0.0-rc.1` remains reserved in governance as the accidental unpublished + prerelease tag and must not be reused for the first real governed RC. +2. Push the governed `pulse/v6-release` branch so `origin` carries the approved + RC candidate and the current release-control records. +3. Run `Pulse Release Pipeline` on `pulse/v6-release` for `6.0.0-rc.2` with the + prepared v6 prerelease notes and rollback input `5.1.27`; create the draft + prerelease first, validate the draft outputs, then publish the prerelease. 4. Keep `rc-to-ga-promotion-readiness` blocked until a real prerelease has shipped and the later GA promotion rehearsal exists. diff --git a/docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-blocked-2026-04-04.md b/docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-blocked-2026-04-04.md index 40c259ff5..6302dde6b 100644 --- a/docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-blocked-2026-04-04.md +++ b/docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-blocked-2026-04-04.md @@ -15,9 +15,9 @@ 4. The governed release profile in `docs/release-control/control_plane.json` currently declares both `prerelease_branch` and `stable_branch` as `pulse/v6-release`. -5. The active control-plane target is still `v6-rc-cut`, not +5. The active control-plane target is still `v6-rc-stabilization`, not `v6-ga-promotion`. -6. The active local `pulse/v6-release` branch currently reports `VERSION=6.0.0-dev`, so the +6. The active local `pulse/v6-release` branch currently reports `VERSION=6.0.0-rc.2`, so the working line is still prerelease and there is not yet a governed local stable `6.0.0` candidate. 7. There is still no governed `Prerelease-to-GA Rehearsal Record` proving a successful @@ -45,14 +45,14 @@ The blocker is no longer missing governance text. The remaining problem is that the control plane still holds v6 on the pre-GA prerelease line, the working -version is still prerelease (`6.0.0-dev`), and there is still no exercised +version is still prerelease (`6.0.0-rc.2`), and there is still no exercised `Release Dry Run` record proving the eventual stable `6.0.0` candidate is ready for GA-style promotion. Until that rehearsal exists, stable users would still be the first real cohort for the final promotion path. ## Required Unblock Steps -1. Promote the active target from `v6-rc-cut` to +1. Promote the active target from `v6-rc-stabilization` to `v6-ga-promotion` only when that change is actually intended. 2. Push the governed `pulse/v6-release` branch state that is intended to become the stable `6.0.0` candidate, including the eventual `VERSION=6.0.0` diff --git a/docs/release-control/v6/internal/status.json b/docs/release-control/v6/internal/status.json index adc83a3d7..0ecf58ede 100644 --- a/docs/release-control/v6/internal/status.json +++ b/docs/release-control/v6/internal/status.json @@ -4222,23 +4222,7 @@ } ], "work_claims": [], - "open_decisions": [ - { - "id": "rc-publication-judgment", - "summary": "Pulse v6 prerelease publication remains an explicit product judgment: the 2026-04-09 packet now records that the enterprise module drift was repaired and the full active-target proof passes, so `rc_ready` remains blocked only until the owner explicitly approves or declines a real governed RC.", - "owner": "project-owner", - "blocking_level": "rc-ready", - "status": "blocked", - "opened_at": "2026-04-04", - "lane_ids": [ - "L1", - "L8", - "L9", - "L12" - ], - "subsystem_ids": [] - } - ], + "open_decisions": [], "source_of_truth_file": "docs/release-control/v6/internal/SOURCE_OF_TRUTH.md", "resolved_decisions": [ { @@ -4659,6 +4643,19 @@ "L15", "L16" ] + }, + { + "id": "rc-publication-judgment", + "summary": "Pulse v6 current `pulse/v6-release` candidate is approved for the first governed RC publication after the 2026-04-09 packet recorded a passing full active-target proof; `rc-publication-judgment` is resolved and prerelease publication may proceed on the governed v6 release line.", + "kind": "release-policy", + "decided_at": "2026-04-09", + "subsystem_ids": [], + "lane_ids": [ + "L1", + "L8", + "L9", + "L12" + ] } ] } diff --git a/docs/releases/RELEASE_NOTES_v6.md b/docs/releases/RELEASE_NOTES_v6.md index a8ffe20b1..12ff4a3a7 100644 --- a/docs/releases/RELEASE_NOTES_v6.md +++ b/docs/releases/RELEASE_NOTES_v6.md @@ -1,6 +1,6 @@ -# Pulse v6.0.0-rc.1 Pre-Release Notes +# Pulse v6.0.0-rc.2 Pre-Release Notes -`v6.0.0-rc.1` is an early Pulse v6 pre-release for users who want to test before the stable `v6.0.0` release. +`v6.0.0-rc.2` is an early Pulse v6 pre-release for users who want to test before the stable `v6.0.0` release. Expect bugs, rough edges, and migration issues. This build is for early testing, not for normal production use. diff --git a/scripts/release_control/release_promotion_policy_test.py b/scripts/release_control/release_promotion_policy_test.py index f32dba5eb..7300b259b 100644 --- a/scripts/release_control/release_promotion_policy_test.py +++ b/scripts/release_control/release_promotion_policy_test.py @@ -240,15 +240,17 @@ class ReleasePromotionPolicyTest(unittest.TestCase): def test_blocked_record_tracks_current_target_and_candidate_version(self) -> None: blocked = read("docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-blocked-2026-04-04.md") + current_version = read("VERSION").strip() + active_target_id = read_json("docs/release-control/control_plane.json")["active_target_id"] self.assertIn("origin/pulse/v6-release", blocked) - self.assertIn("VERSION=6.0.0-dev", blocked) + self.assertIn(f"VERSION={current_version}", blocked) self.assertIn("artifact-owned candidate stable tag", blocked) self.assertIn("artifact-owned promotion channel", blocked) self.assertIn("artifact-owned promoted prerelease tag", blocked) self.assertIn("artifact-owned rollback target", blocked) self.assertIn("Materialize the final rehearsal record from that artifact without", blocked) self.assertIn("hand-repairing any missing candidate tag, promoted prerelease tag, rollback", blocked) - self.assertIn("The active control-plane target is still `v6-rc-cut`, not", blocked) + self.assertIn(f"The active control-plane target is still `{active_target_id}`, not", blocked) matrix = read("docs/release-control/v6/internal/HIGH_RISK_RELEASE_VERIFICATION_MATRIX.md") self.assertIn(promotion_metadata_envelope(), normalize_ws(matrix)) expected = blocked_record.build_blocked_record(record_date="2026-04-04")