diff --git a/.github/ISSUE_TEMPLATE/release_train.yml b/.github/ISSUE_TEMPLATE/release_train.yml new file mode 100644 index 0000000..3d113c6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release_train.yml @@ -0,0 +1,68 @@ +name: Release Train +description: Governed release train for an OMT-Global repository +title: "Release: vX.Y.Z" +labels: + - release:train + - review:release +body: + - type: input + id: version + attributes: + label: Version + placeholder: v1.2.3 or v1.2.3-rc.1 + validations: + required: true + + - type: dropdown + id: channel + attributes: + label: Channel + options: + - rc + - beta + - stable + - maintenance + validations: + required: true + + - type: input + id: release_branch + attributes: + label: Release branch + placeholder: release/1.2 + + - type: input + id: target_sha + attributes: + label: Target SHA + placeholder: Full commit SHA for the release candidate + + - type: textarea + id: scope + attributes: + label: Scope + description: User-facing changes, fixes, risks, exclusions. + validations: + required: true + + - type: textarea + id: gates + attributes: + label: Gates + value: | + - [ ] Release branch created + - [ ] Scope locked + - [ ] Changelog/release notes prepared + - [ ] Version surfaces updated + - [ ] Preflight passed + - [ ] preflight_run_id recorded: + - [ ] Full validation passed + - [ ] validation_run_id recorded: + - [ ] Exact tag created + - [ ] Publish approval granted + - [ ] Artifacts published + - [ ] GitHub Release created or updated + - [ ] Release evidence uploaded + - [ ] Postpublish verification passed + - [ ] Floating tags/channels promoted if applicable + - [ ] Release issue closed diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ac6bf5b..57bb1ba 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,7 +4,7 @@ ## Governing Issue -Closes # +Refs # ## Validation @@ -16,7 +16,7 @@ Closes # - [ ] Changes are scoped to the linked issue - [ ] Contributor or PR guidance changes are reflected in `CONTRIBUTING.md`, `.github/PULL_REQUEST_TEMPLATE.md`, and `docs/bootstrap/onboarding.md` when applicable -- [ ] Auto-merge is enabled, or GitHub plan-limit evidence is recorded and the fallback merge-readiness policy applies +- [ ] PR author enabled auto-merge where GitHub allows it, or GitHub plan-limit evidence/unavailable reason is recorded and the fallback merge-readiness policy applies - [ ] No real secrets, runtime auth, or machine-local env files are committed ## Flow Contract @@ -31,11 +31,11 @@ Closes # - [ ] Every blocker has a next actor and next action - [ ] No active blocking requested changes remain - [ ] Non-author approval is present when required -- [ ] Auto-merge is appropriate when gates pass +- [ ] PR author enabled auto-merge where GitHub allows it, or recorded why it is unavailable/unsafe ## Merge Automation -- [ ] Auto-merge is enabled, or the reason it is unavailable or unsafe is noted below +- [ ] PR author enabled auto-merge with `gh pr merge --auto --squash`, or the reason it is unavailable/unsafe is noted below ## Notes diff --git a/FLOW.md b/FLOW.md index 9ee587f..b20e4db 100644 --- a/FLOW.md +++ b/FLOW.md @@ -48,6 +48,21 @@ Canonical states: 15. `Blocked - Scope` 16. `Paused` +### Release states + +Release work uses the same GitHub-visible control plane, with the detailed release state machine defined in `docs/release-flow.md`. + +Canonical release states include `Release Intake`, `Release Scope Locked`, `Release Branch Open`, `Release Prep`, `Preflight Running`, `Preflight Passed`, `Full Validation Running`, `Full Validation Passed`, `Tag Ready`, `Publish Approval Required`, `Publishing`, `Published`, `Postpublish Verification`, `Promoted`, `Release Closed`, the release-specific blocked states, and `Release Rolled Back / Superseded`. + +Release actor responsibilities: + +- Pheidon: release controller, approval gate, final publish decision. +- Apollo: release issue quality, scope lock, release notes, changelog quality. +- Daedalus: release fixes, version bumps, artifact build repair. +- Ares: adversarial validation, regression pressure, security/risk review. +- Hephaestus: CI, lockfiles, workflow health, artifact generation, evidence, publish mechanics. +- Hermes: platform-native validation where relevant, especially macOS/native packaging. + ## Controller loop The controller repeatedly: @@ -66,6 +81,8 @@ The controller repeatedly: Open PR clearance has priority over starting new implementation work. +During release freeze, PR-first still applies, but release-blocking PRs take priority over net-new feature work. + Priority order: 1. merge clean approved green PRs; @@ -92,3 +109,5 @@ A unit of work is done only when: - the linked issue is closed or intentionally reclassified; - flow state is updated; - no worker lane retains stale active state for it. + +A release is done only when the release issue is closed or intentionally superseded, the release branch is merged or intentionally retained, the exact tag and GitHub Release or prerelease exist, release evidence is uploaded, preflight and validation run IDs are recorded, publish and postpublish evidence are recorded when applicable, channels are promoted when applicable, and no worker lane retains stale active state. diff --git a/README.md b/README.md index 1bf55c6..2e7c9f8 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,13 @@ bash scripts/ci/run-fast-checks.sh - Visibility: `public` - Default branch: `main` - Archetype: `generic-empty` + +## Release Standard + +This repository uses release maturity level `simple`. Level 1 `simple` keeps immutable exact SemVer tags such as `v1.2.3`, then automatically advances the floating compatibility tags `v1.2` and `v1` to the same commit. Level 2 `governed` adds preflight, full validation, explicit publish approval, postpublish verification, and release evidence. + +Cut patch releases from `release/X.Y` branches when you maintain an older minor line. Cut new minor and major releases from `main`. + +## Repository URL + +- https://github.com/OMT-Global/flow diff --git a/docs/omt-global-operating-map.md b/docs/omt-global-operating-map.md index b93e107..e25aed6 100644 --- a/docs/omt-global-operating-map.md +++ b/docs/omt-global-operating-map.md @@ -22,6 +22,16 @@ flowchart TD Repo -->|state changes feed the next loop| Flow ``` +Release train path: + +```text +Flow policy + -> Bootstrap projection + -> Repo release issue/workflows + -> Pheidon approval + -> Published release + evidence +``` + ## Mental Model - `OMT-Global/flow` is the operating protocol for the organization. It defines how work moves through issues, PRs, reviews, repairs, checks, merge gates, and worker lanes. diff --git a/docs/release-flow.md b/docs/release-flow.md new file mode 100644 index 0000000..c765844 --- /dev/null +++ b/docs/release-flow.md @@ -0,0 +1,85 @@ +# Governed Release Flow + +OMT governed releases use GitHub issues, release branches, validation-only workflows, explicit publish approval, and attached evidence to keep release state durable and inspectable. + +## Principles + +- GitHub issue is the durable release-train record. +- Release branch isolates release prep and release fixes from mainline work. +- Preflight proves package and artifact shape without publishing. +- Full validation proves release readiness without mutating production surfaces. +- Publish is the only mutating path. +- Publish consumes the same artifact proven by preflight. +- Release evidence must be attached to the GitHub Release. +- Postpublish verification closes the loop. + +## Lanes + +- `dev`: `main` branch, moving head. +- `rc`: `vX.Y.Z-rc.N` or `vX.Y.Z-beta.N`. +- `stable`: `vX.Y.Z`. +- `maintenance`: `release/X.Y` plus `vX.Y.Z` patch tags. + +SemVer is the default OMT project versioning model because bootstrap already projects SemVer release automation. + +## State Machine + +Canonical release states: + +1. `Release Intake` +2. `Release Scope Locked` +3. `Release Branch Open` +4. `Release Prep` +5. `Preflight Running` +6. `Preflight Passed` +7. `Full Validation Running` +8. `Full Validation Passed` +9. `Tag Ready` +10. `Publish Approval Required` +11. `Publishing` +12. `Published` +13. `Postpublish Verification` +14. `Promoted` +15. `Release Closed` +16. `Release Blocked - Human` +17. `Release Blocked - CI` +18. `Release Blocked - Security` +19. `Release Blocked - Artifact` +20. `Release Rolled Back / Superseded` + +## Actors + +- Pheidon: release controller, approval gate, final publish decision. +- Apollo: release issue quality, scope lock, release notes, changelog quality. +- Daedalus: release fixes, version bumps, artifact build repair. +- Ares: adversarial validation, regression pressure, security/risk review. +- Hephaestus: CI, lockfiles, workflow health, artifact generation, evidence, publish mechanics. +- Hermes: platform-native validation where relevant, especially macOS/native packaging. + +## Done Definition + +A release is done only when: + +- release issue is closed or intentionally superseded; +- release branch is merged or intentionally retained for maintenance; +- exact tag exists; +- GitHub Release or prerelease exists; +- release evidence is uploaded; +- preflight run ID is recorded; +- validation run ID is recorded; +- publish run ID is recorded if publishing occurred; +- postpublish verification passed or was explicitly waived with rationale; +- floating tags/channels were promoted if applicable; +- no worker lane retains stale active state. + +## Block Handling + +`Release Blocked - Human`: record the decision needed, the accountable approver, and the next review checkpoint on the release issue. Do not publish until the decision is resolved. + +`Release Blocked - CI`: link the failing workflow run, assign Hephaestus or the relevant implementation owner, and keep the release issue open until the rerun passes or the release is superseded. + +`Release Blocked - Security`: assign Ares and the code owner, capture the risk and mitigation, and require explicit release-owner approval before continuing. + +`Release Blocked - Artifact`: keep the candidate artifact immutable, repair with a new release fix commit, and rerun preflight so publish consumes newly proven artifacts. + +`Release Rolled Back / Superseded`: record the successor release issue or tag, preserve the published release evidence, and close the old train as superseded. Do not delete or rewrite published prerelease tags; cut the next prerelease number. diff --git a/github/labels.yaml b/github/labels.yaml index 2b523f8..214fe8d 100644 --- a/github/labels.yaml +++ b/github/labels.yaml @@ -98,6 +98,43 @@ color: "bc80bd" description: Policy, flow, bootstrap, or governance work. +- name: release:train + color: "5319e7" + description: Release train tracking issue. +- name: release:scope-locked + color: "0052cc" + description: Release scope is locked except release fixes. +- name: release:preflight + color: "1d76db" + description: Release preflight is running or required. +- name: release:validation + color: "fbca04" + description: Full release validation is running or required. +- name: release:publish-ready + color: "0e8a16" + description: Release has required evidence and is ready for approval. +- name: release:blocked + color: "b60205" + description: Release is blocked. +- name: release:published + color: "0e8a16" + description: Release has been published. +- name: release:superseded + color: "cfd3d7" + description: Release was superseded by a later candidate or release. +- name: channel:rc + color: "c5def5" + description: Release candidate or beta channel. +- name: channel:stable + color: "0e8a16" + description: Stable release channel. +- name: channel:maintenance + color: "fbca04" + description: Maintenance release channel. +- name: review:release + color: "f9d0c4" + description: Needs release-owner review. + - name: priority:p0 color: "e41a1c" description: Critical/urgent. diff --git a/policies/release-policy.yaml b/policies/release-policy.yaml new file mode 100644 index 0000000..c6e8044 --- /dev/null +++ b/policies/release-policy.yaml @@ -0,0 +1,32 @@ +version: 1 +release: + defaultVersioning: semver + defaultMaturity: simple + releaseBranchPattern: release/{major}.{minor} + lanes: + dev: + ref: main + rc: + tagPatterns: + - v*.*.*-rc.* + - v*.*.*-beta.* + stable: + tagPatterns: + - v*.*.* + maintenance: + branchPattern: release/{major}.{minor} + requiredEvidence: + - release_issue + - target_sha + - preflight_run_id + - validation_run_id + - release_notes + - artifact_checksums + - postpublish_status + actors: + controller: Pheidon + scope: Apollo + implementation: Daedalus + validation: Ares + ci_artifacts: Hephaestus + platform_native: Hermes diff --git a/project.bootstrap.yaml b/project.bootstrap.yaml index 62e2467..20cbe2d 100644 --- a/project.bootstrap.yaml +++ b/project.bootstrap.yaml @@ -14,6 +14,7 @@ repo: - .github/PULL_REQUEST_TEMPLATE.md - .github/ISSUE_TEMPLATE/implementation.yml - .github/ISSUE_TEMPLATE/flow_blocker.yml + - .github/ISSUE_TEMPLATE/release_train.yml archetype: kind: generic-empty github: