diff --git a/docs/release-control/control_plane.json b/docs/release-control/control_plane.json index f8bb48af4..5086d1513 100644 --- a/docs/release-control/control_plane.json +++ b/docs/release-control/control_plane.json @@ -55,7 +55,7 @@ "profile_id": "v6", "kind": "release", "status": "active", - "summary": "Prepare Pulse v6 GA from the current pulse/v6-release branch after accumulated post-RC7 fixes and final current-branch validation. Do not promote the published RC7 candidate unchanged, and do not plan another RC by default; remaining release-day execution and public cutover approval require fresh current-branch proof, while newly reported RC7 issues stay regression signals unless a release-owner decision changes direction.", + "summary": "Prepare Pulse v6 GA from the current pulse/v6-release branch after accumulated post-RC7 fixes. Do not promote the published RC7 candidate unchanged, and do not plan another RC by default; on 2026-07-02 the release owner accepted the remaining current-branch validation risk for GA rather than requiring RC8 or another soak, while newly reported RC7 issues stay regression signals unless a release-owner decision changes direction and release-day execution plus public cutover still require explicit owner approval.", "completion_rule": "manual", "proof_scope": "none" }, diff --git a/docs/release-control/v6/internal/HIGH_RISK_RELEASE_VERIFICATION_MATRIX.md b/docs/release-control/v6/internal/HIGH_RISK_RELEASE_VERIFICATION_MATRIX.md index 20e4874eb..9b8e61e3c 100644 --- a/docs/release-control/v6/internal/HIGH_RISK_RELEASE_VERIFICATION_MATRIX.md +++ b/docs/release-control/v6/internal/HIGH_RISK_RELEASE_VERIFICATION_MATRIX.md @@ -454,17 +454,25 @@ Companion drill: URL in the release ticket or rehearsal record. 8. Confirm the migration gate and other applicable high-risk gates are cleared for this same candidate before broad rollout. + 9. For v6.0.0 only, confirm the 2026-07-02 owner risk acceptance is recorded + if the current branch contains post-RC7 changes that will ship without + RC8, another soak, or additional current-branch validation before GA. - Pass when: Stable or GA promotion is a governed handoff from an exercised prerelease with live release-pipeline proof, explicit rollback instructions, and the published v5 maintenance policy plus exact end-of-support date, with a linked rehearsal run URL and dry-run artifact carrying the full canonical promotion metadata - envelope. + envelope. For v6.0.0 only, the recorded 2026-07-02 owner risk acceptance may + clear the remaining current-branch validation risk without implying the + post-RC7 changes were RC-tested. - Latest exercised record: - `docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-2026-04-20.md` + `docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-2026-06-04.md` +- Owner risk acceptance: + `docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md` - Block release if: - Stable users would become the first real validation cohort, the rollback - target is unclear, or the v5 maintenance-only policy is still undecided. + Stable users would become the first real validation cohort without explicit + owner risk acceptance, the rollback target is unclear, or the v5 + maintenance-only policy is still undecided. ## Gate: `upgrade-state-and-entitlement-preservation` diff --git a/docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md b/docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md index 5eb151c57..74fa5305d 100644 --- a/docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md +++ b/docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md @@ -19,16 +19,17 @@ Use this as the final gate before cutting a Pulse v6 pre-release. - The latest RC publication judgment packet is `docs/release-control/v6/internal/records/rc-publication-judgment-packet-2026-04-09.md`. It now records approval, not a proof blocker. -- The active target is now `v6-product-lane-expansion`; the stable promotion - packet is no longer the only release-ready concern, and release-ready gates - must still fail closed if the product truth changes. -- `rc-to-ga-promotion-readiness` was cleared on 2026-04-20 by `Release Dry Run` - run `24673393628`, recorded at - `docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-2026-04-20.md`. -- The stable `6.0.0` candidate now has an exercised non-publish promotion - rehearsal carrying the canonical promotion artifact envelope: candidate - stable tag, promotion channel, promoted prerelease tag, rollback target, - exact rollback command, exact GA date, and exact v5 end-of-support inputs. +- The active target is now `v6-ga-promotion`; lane expansion stays planned + behind GA. +- The stable `6.0.0` candidate is the current `pulse/v6-release` branch after + accumulated post-RC7 changes, not the published RC7 candidate unchanged. +- `rc-to-ga-promotion-readiness` is cleared for v6.0.0 by the prior governed + release-pipeline rehearsals plus the 2026-07-02 release-owner risk + acceptance recorded at + `docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md`. +- The release-owner acceptance is not validation evidence for the post-RC7 + changes. It is the explicit decision to ship the current branch without RC8, + another soak, or additional current-branch validation before GA. - `known-rc-issue-closure-for-ga` was introduced on 2026-04-21 to reflect the locked rule that v6 GA must be feature-complete relative to the prerelease issue set. It is currently blocked on the dated RC issue-closure packet. @@ -38,11 +39,11 @@ Use this as the final gate before cutting a Pulse v6 pre-release. ## Promotion Policy - [x] Record the previous stable tag and exact rollback pin command before publishing a new prerelease or stable release. - [ ] For any prerelease or stable publication, confirm the repo variable `PULSE_UPDATE_SIGNING_PUBLIC_KEY` is set to the intended active update signer public key and that the release workflows are consuming it alongside `PULSE_UPDATE_SIGNING_KEY`, so accidental trust-root rotation fails closed before publication. -- [ ] For the GA/stable candidate, confirm the release pipeline has already been exercised on a real prerelease tag, not only linted or YAML-parsed. +- [x] For the GA/stable candidate, confirm the release pipeline has already been exercised on a real prerelease tag, not only linted or YAML-parsed. - [x] For stable promotion, confirm the candidate commit has already shipped on `rc`. - [x] For stable promotion, confirm the chosen `promoted_from_tag` is a prerelease that was actually published through the governed prerelease path, not an accidental git tag. - [x] For stable promotion, confirm the prerelease soak window is at least 72 hours or document the hotfix exception explicitly. -- [ ] For stable promotion, confirm paid production tenants are not being moved onto an unvalidated build. +- [x] For stable promotion, record the 2026-07-02 release-owner decision accepting the current-branch validation risk for the post-RC7 changes. - [x] For GA/stable promotion, confirm `V5_MAINTENANCE_SUPPORT_POLICY.md` is still the intended policy and replace any placeholder GA notice dates with the exact v6 GA date and exact v5 end-of-support date that will ship with the announcement. - [x] For GA/stable promotion, confirm the pushed governed release-branch copy of `.github/workflows/release-dry-run.yml` already accepts the governed stable rehearsal metadata envelope (`promoted_from_tag`, `rollback_version`, `ga_date`, `v5_eos_date`) through `workflow_dispatch`, because GitHub executes the selected remote ref and does not see local-only governance state. - [x] For GA/stable promotion, confirm the local rehearsal branch exactly matches `origin` before dispatching `Release Dry Run`, so the run exercises the intended governed branch state instead of stale remote control-plane metadata. diff --git a/docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md b/docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md index 1513c2f30..12a596bdc 100644 --- a/docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md +++ b/docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md @@ -147,6 +147,18 @@ Cloud, and self-hosted production users. customer harm. - The exception plus the rollback target and exact reinstall command must be recorded in the release notes or release ticket before promotion. +7. v6.0.0 owner-risk exception: + - On 2026-07-02, after seven v6 release candidates, the release owner + explicitly approved promoting the current `pulse/v6-release` branch with + accumulated post-RC7 changes without RC8, another soak, or additional + current-branch validation before GA. + - This is a bounded v6.0.0 release-owner risk acceptance, not validation + evidence for the post-RC7 changes and not a standing policy for later + stable releases. + - The release packet must describe the GA candidate honestly as the current + branch after the RC line, keep rollback and v5 maintenance dates explicit, + and retain the prior governed release-pipeline rehearsal evidence as + automation lineage rather than claiming the post-RC7 changes were RC-tested. ## Rollout Rules diff --git a/docs/release-control/v6/internal/SOURCE_OF_TRUTH.md b/docs/release-control/v6/internal/SOURCE_OF_TRUTH.md index 2996ac548..a158c541f 100644 --- a/docs/release-control/v6/internal/SOURCE_OF_TRUTH.md +++ b/docs/release-control/v6/internal/SOURCE_OF_TRUTH.md @@ -1,6 +1,6 @@ # Pulse v6 Source Of Truth -Last updated: 2026-06-26 +Last updated: 2026-07-02 Status: ACTIVE This file is the stable human governance layer for the active v6 release @@ -470,7 +470,11 @@ Assertion design rules: architectural blockers. 7. Stable or GA promotion for v6 must come from an exercised RC and stay blocked until the RC-to-GA promotion gate is cleared and the published v5 - maintenance-policy notice is ready. + maintenance-policy notice is ready. For v6.0.0 only, the 2026-07-02 + release-owner risk acceptance allows the current post-RC7 `pulse/v6-release` + branch to ship without RC8, another soak, or additional current-branch + validation before GA; this is not validation evidence and not a standing + stable-promotion rule for later releases. 8. v6 and later releases use a promotion model, not a direct broad-rollout model. `stable` must receive only promoted, already-validated builds, `rc` is the diff --git a/docs/release-control/v6/internal/V5_MAINTENANCE_SUPPORT_POLICY.md b/docs/release-control/v6/internal/V5_MAINTENANCE_SUPPORT_POLICY.md index 139763e08..957901c18 100644 --- a/docs/release-control/v6/internal/V5_MAINTENANCE_SUPPORT_POLICY.md +++ b/docs/release-control/v6/internal/V5_MAINTENANCE_SUPPORT_POLICY.md @@ -64,8 +64,8 @@ These do not qualify as v5 maintenance work: The first stable `v6.0.0` release must publish this exact notice: -> Pulse v5 entered maintenance-only support on 2026-06-04. I will ship only +> Pulse v5 entered maintenance-only support on 2026-07-02. I will ship only > critical security, data-loss, licensing or billing blocker, installer or > updater failure, and safe migration blocker fixes for existing v5 users until -> 2026-09-02. After 2026-09-02, Pulse v5 is end-of-support and new fixes land +> 2026-09-30. After 2026-09-30, Pulse v5 is end-of-support and new fixes land > on v6 unless I publish an explicit exception. diff --git a/docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md b/docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md new file mode 100644 index 000000000..3a0451533 --- /dev/null +++ b/docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md @@ -0,0 +1,36 @@ +# Current Branch GA Owner Approval + +- Decision date: 2026-07-02 +- Release target: Pulse v6.0.0 GA +- Release branch: `pulse/v6-release` +- Scope decision: include accumulated post-RC7 changes in the GA release +- Additional RC or soak required: no +- Additional current-branch validation required before GA: no +- GA date for publication packet: 2026-07-02 +- v5 end-of-support date for publication packet: 2026-09-30 + +## Owner Direction + +The release owner explicitly approved shipping the current v6 release branch as +the GA scope even though the post-RC7 changes have not received another RC or +soak cycle. + +This record is risk acceptance, not validation evidence. The release record +must not describe the post-RC7 changes as RC-tested. The public release packet +must describe v6.0.0 as the current branch GA after seven release candidates, +with the exact GA and v5 end-of-support dates updated for the actual July 2, +2026 launch decision. + +## Release-Control Impact + +For v6.0.0 only, `rc-to-ga-promotion-readiness` may be treated as cleared by +the combination of: + +1. prior governed release-pipeline rehearsal evidence for v6.0.0, +2. explicit rollback target and reinstall command, +3. the written v5 maintenance-only policy, +4. the current-branch GA policy record, and +5. this owner approval accepting the remaining current-branch validation risk. + +This bounded exception must not become the default stable-promotion rule for +future releases. diff --git a/docs/release-control/v6/internal/records/current-branch-ga-release-policy-2026-07-01.md b/docs/release-control/v6/internal/records/current-branch-ga-release-policy-2026-07-01.md index 6513d9185..350476b05 100644 --- a/docs/release-control/v6/internal/records/current-branch-ga-release-policy-2026-07-01.md +++ b/docs/release-control/v6/internal/records/current-branch-ga-release-policy-2026-07-01.md @@ -3,18 +3,28 @@ ## Direction The next public Pulse v6 release target is GA from the current -`pulse/v6-release` branch after accumulated post-RC7 fixes and final -current-branch validation. +`pulse/v6-release` branch after accumulated post-RC7 fixes. The published RC7 candidate must not be promoted unchanged. Another RC is not planned by default; seven RC releases are enough unless the release owner explicitly changes direction. +## Owner risk acceptance + +On 2026-07-02, the release owner explicitly accepted the accumulated post-RC7 +changes for the v6.0.0 GA release without requiring RC8, another soak, or +additional current-branch validation before GA. + +This is a release-owner risk acceptance, not proof that the post-RC7 branch +state received RC validation. Future stable releases still inherit the normal +promotion policy unless a separate owner decision records a bounded exception. + ## Release-control impact The historical RC7 readiness evidence remains useful as prerelease lineage evidence, but it no longer proves the final GA candidate by itself because the current branch intentionally contains additional fixes and changes after RC7. -The GA promotion readiness gate therefore stays pending until the current -branch has final GA validation and publication approval. +The GA promotion readiness gate may clear for v6.0.0 only with this owner risk +acceptance recorded alongside the prior release-pipeline rehearsal, rollback +target, v5 maintenance policy, and explicit publication approval. diff --git a/docs/release-control/v6/internal/status.json b/docs/release-control/v6/internal/status.json index 9d9e0e06f..b4a7bc135 100644 --- a/docs/release-control/v6/internal/status.json +++ b/docs/release-control/v6/internal/status.json @@ -1,6 +1,6 @@ { "version": "6.0", - "updated_at": "2026-06-26", + "updated_at": "2026-07-02", "scope": { "active_repos": [ "pulse", @@ -664,6 +664,16 @@ "path": "docs/release-control/v6/internal/RC_TO_GA_REHEARSAL_TEMPLATE.md", "kind": "file" }, + { + "repo": "pulse", + "path": "docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md", + "kind": "file" + }, + { + "repo": "pulse", + "path": "docs/release-control/v6/internal/records/current-branch-ga-release-policy-2026-07-01.md", + "kind": "file" + }, { "repo": "pulse", "path": "docs/release-control/v6/internal/records/known-rc-issue-closure-for-ga-blocked-2026-04-21.md", @@ -694,6 +704,11 @@ "path": "docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-2026-04-20.md", "kind": "file" }, + { + "repo": "pulse", + "path": "docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-2026-06-04.md", + "kind": "file" + }, { "repo": "pulse", "path": "docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-blocked-2026-03-26.md", @@ -6597,11 +6612,11 @@ }, { "id": "rc-to-ga-promotion-readiness", - "summary": "Confirm Pulse v6 GA promotion is coming from the current pulse/v6-release branch after accumulated post-RC7 fixes, final current-branch validation, rollback instructions, and a written v5 maintenance-only policy.", + "summary": "Confirm Pulse v6 GA promotion is coming from the current pulse/v6-release branch after accumulated post-RC7 fixes, with the 2026-07-02 owner risk acceptance for no RC8 or further current-branch validation, rollback instructions, and a written v5 maintenance-only policy.", "owner": "project-owner", "blocking_level": "release-ready", "minimum_evidence_tier": "real-external-e2e", - "status": "pending", + "status": "passed", "verification_doc": "docs/release-control/v6/internal/HIGH_RISK_RELEASE_VERIFICATION_MATRIX.md", "lane_ids": [ "L1", @@ -6610,6 +6625,12 @@ "L12" ], "evidence": [ + { + "repo": "pulse", + "path": "docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md", + "kind": "file", + "evidence_tier": "local-rehearsal" + }, { "repo": "pulse", "path": "docs/release-control/v6/internal/records/current-branch-ga-release-policy-2026-07-01.md", @@ -6646,6 +6667,12 @@ "kind": "file", "evidence_tier": "real-external-e2e" }, + { + "repo": "pulse", + "path": "docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-2026-06-04.md", + "kind": "file", + "evidence_tier": "real-external-e2e" + }, { "repo": "pulse", "path": "docs/release-control/v6/internal/records/rc-to-ga-promotion-readiness-rehearsal-blocked-2026-03-26.md", @@ -8169,7 +8196,7 @@ }, { "id": "current-branch-ga-no-rc8-default", - "summary": "The next public v6 release target is GA from current pulse/v6-release after accumulated post-RC7 fixes and final validation. Do not promote RC7 unchanged, and do not plan RC8 by default unless the release owner changes direction.", + "summary": "The next public v6 release target is GA from current pulse/v6-release after accumulated post-RC7 fixes. Do not promote RC7 unchanged, and do not plan RC8 by default unless the release owner changes direction.", "kind": "release-policy", "decided_at": "2026-07-01", "subsystem_ids": [], @@ -8180,6 +8207,20 @@ "L9", "L12" ] + }, + { + "id": "current-branch-ga-owner-risk-acceptance", + "summary": "On 2026-07-02 the release owner accepted the accumulated post-RC7 pulse/v6-release branch changes for v6.0.0 GA without RC8, another soak, or additional current-branch validation before GA; this is a bounded release-owner risk acceptance, not validation evidence for the post-RC7 changes.", + "kind": "release-policy", + "decided_at": "2026-07-02", + "subsystem_ids": [], + "lane_ids": [ + "L1", + "L2", + "L5", + "L9", + "L12" + ] } ] } diff --git a/docs/release-control/v6/internal/subsystems/deployment-installability.md b/docs/release-control/v6/internal/subsystems/deployment-installability.md index 22897b400..11f7152e0 100644 --- a/docs/release-control/v6/internal/subsystems/deployment-installability.md +++ b/docs/release-control/v6/internal/subsystems/deployment-installability.md @@ -588,9 +588,9 @@ TLS floor in the dynamic config. rollback target, exact GA date, and exact v5 end-of-support date aligned across release notes, upgrade guidance, support policy, promotion records, and release-promotion resolver proof before workflow dispatch. For the - 2026-06-04 cutover candidate, that packet is - `promoted_from_tag=v6.0.0-rc.6`, `rollback_version=v5.1.34`, - `ga_date=2026-06-04`, and `v5_eos_date=2026-09-02`. + 2026-07-02 cutover candidate, that packet is + `promoted_from_tag=v6.0.0-rc.7`, `rollback_version=v5.1.34`, + `ga_date=2026-07-02`, and `v5_eos_date=2026-09-30`. That stable cut must also move the repo-root Docker compose default and `scripts/install-docker.sh` fallback from the final RC image tag to the stable `6.0.0` image tag in the same commit as `VERSION=6.0.0`. diff --git a/docs/releases/RELEASE_NOTES_v6.md b/docs/releases/RELEASE_NOTES_v6.md index 4a107404b..e8ae09fe3 100644 --- a/docs/releases/RELEASE_NOTES_v6.md +++ b/docs/releases/RELEASE_NOTES_v6.md @@ -1,7 +1,8 @@ # Pulse v6.0.0 Release Notes -`v6.0.0` is the first stable release of Pulse v6. It promotes the validated -`v6.0.0-rc.6` candidate into the default supported v6 release. +`v6.0.0` is the first stable release of Pulse v6. It promotes the current +`pulse/v6-release` branch into the default supported v6 release after seven +release candidates and accumulated post-RC7 fixes. Pulse v6 keeps the platform-shaped top-level navigation existing v5 operators already know (Proxmox, Docker, Kubernetes, TrueNAS, vSphere, Machines, plus @@ -15,16 +16,17 @@ RC line. The v6 line briefly shipped a unified `Infrastructure` / `Workloads` / `Storage` / `Recovery` top-level layout across `rc.1` through `rc.5`. Operator feedback consistently preferred the platform-shaped navigation v5 already had, -so I reverted the frontend information architecture in `rc.6` to platform- -shaped pages while keeping the unified resource model on the backend. Same -backend, the navigation shape you already know. +so I reverted the frontend information architecture in `rc.6` and kept that +platform-shaped direction through the final release branch while preserving the +unified resource model on the backend. Same backend, the navigation shape you +already know. ## Pulse v5 Support Transition -Pulse v5 entered maintenance-only support on `2026-06-04`. +Pulse v5 entered maintenance-only support on `2026-07-02`. I will ship only critical security, data-loss, licensing or billing blocker, -installer or updater failure, and safe migration blocker fixes for existing v5 users until `2026-09-02`. -After `2026-09-02`, Pulse v5 is end-of-support and new fixes land on v6 unless +installer or updater failure, and safe migration blocker fixes for existing v5 users until `2026-09-30`. +After `2026-09-30`, Pulse v5 is end-of-support and new fixes land on v6 unless I publish an explicit exception. ## What Is In v6.0.0 diff --git a/scripts/release_control/release_promotion_policy_test.py b/scripts/release_control/release_promotion_policy_test.py index dc94d2e6a..ff45d88f4 100644 --- a/scripts/release_control/release_promotion_policy_test.py +++ b/scripts/release_control/release_promotion_policy_test.py @@ -134,6 +134,58 @@ class ReleasePromotionPolicyTest(unittest.TestCase): self.assertIn("license.pulserelay.pro/pulse-pro:6.0.0", content) self.assertIn("moving branch", content) + def test_v6_ga_owner_risk_exception_is_bounded_and_packet_aligned(self) -> None: + policy = read("docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md") + checklist = read("docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md") + owner_record = read( + "docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md" + ) + release_notes = read("docs/releases/RELEASE_NOTES_v6.md") + v5_policy = read("docs/release-control/v6/internal/V5_MAINTENANCE_SUPPORT_POLICY.md") + status = read_json("docs/release-control/v6/internal/status.json") + control_plane = read_json("docs/release-control/control_plane.json") + + normalized_policy = normalize_ws(policy) + normalized_checklist = normalize_ws(checklist) + normalized_owner_record = normalize_ws(owner_record) + normalized_release_notes = normalize_ws(release_notes) + normalized_v5_policy = normalize_ws(v5_policy) + + self.assertIn("v6.0.0 owner-risk exception", policy) + self.assertIn("bounded v6.0.0 release-owner risk acceptance", normalized_policy) + self.assertIn("not validation evidence for the post-RC7 changes", normalized_policy) + self.assertIn("not a standing policy for later stable releases", normalized_policy) + self.assertIn("Additional RC or soak required: no", normalized_owner_record) + self.assertIn("Additional current-branch validation required before GA: no", normalized_owner_record) + self.assertIn("accepting the remaining current-branch validation risk", normalized_owner_record) + self.assertIn("not validation evidence for the post-RC7", normalized_checklist) + + self.assertIn("current `pulse/v6-release` branch", normalized_release_notes) + self.assertIn("seven release candidates and accumulated post-RC7 fixes", normalized_release_notes) + self.assertIn("Pulse v5 entered maintenance-only support on `2026-07-02`.", normalized_release_notes) + self.assertIn("existing v5 users until `2026-09-30`.", normalized_release_notes) + self.assertIn("Pulse v5 entered maintenance-only support on 2026-07-02.", normalized_v5_policy) + self.assertIn("2026-09-30. After 2026-09-30", normalized_v5_policy) + + gate = next(gate for gate in status["release_gates"] if gate["id"] == "rc-to-ga-promotion-readiness") + self.assertEqual(gate["status"], "passed") + self.assertIn("owner risk acceptance", gate["summary"]) + self.assertIn( + "docs/release-control/v6/internal/records/current-branch-ga-owner-approval-2026-07-02.md", + {item["path"] for item in gate["evidence"]}, + ) + + decisions = {decision["id"]: decision for decision in status["resolved_decisions"]} + self.assertEqual( + decisions["current-branch-ga-owner-risk-acceptance"]["decided_at"], + "2026-07-02", + ) + + active_target = next( + target for target in control_plane["targets"] if target["id"] == control_plane["active_target_id"] + ) + self.assertIn("accepted the remaining current-branch validation risk", active_target["summary"]) + def test_pre_release_checklist_tracks_rc_to_ga_gate_inputs(self) -> None: content = read("docs/release-control/v6/internal/PRE_RELEASE_CHECKLIST.md") self.assertIn("release pipeline has already been exercised on a real prerelease tag", content)