Record v6 GA owner approval

This commit is contained in:
rcourtman 2026-07-02 21:33:37 +01:00
parent 6c9b4f8e8d
commit aa1913d0bb
12 changed files with 206 additions and 40 deletions

View file

@ -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"
},

View file

@ -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`

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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"
]
}
]
}

View file

@ -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`.

View file

@ -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

View file

@ -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)